5. Acceso a datos: integración de EntityFramework

prefacio

MasaProporciona EntityFrameworkintegración de datos basada en datos y proporciona funciones de filtrado de datos y eliminación suave. A continuación, presentaremos cómo usarlo.

Primeros pasos con MasaDbContext

  1. Cree un nuevo proyecto vacío de ASP.NET Core Assignment.MasaEntityFrameworke instale Masa.Contrib.Data.EntityFrameworkCore, Swashbuckle.AspNetCore, Microsoft.EntityFrameworkCore.InMemory,Microsoft.EntityFrameworkCore.Tools

    dotnet add package Masa.Contrib.Data.EntityFrameworkCore --version 0.4.0-rc.4
    dotnet add package Swashbuckle.AspNetCore --version 6.2.3
    dotnet add package Microsoft.EntityFrameworkCore.InMemory --version 6.0.5
    dotnet add package Microsoft.EntityFrameworkCore.Tools --version 6.0.5
    

    La instalación Swashbuckle.AspNetCorees para la conveniencia Swaggerde operar el servicio. La instalación Microsoft.EntityFrameworkCore.InMemoryes para la conveniencia, así que use la base de datos en memoria. Si necesita usar otras bases de datos, instale el paquete correspondiente usted mismo. La instalación Microsoft.EntityFrameworkCore.Toolses para usar CodeFirst para crear una base de datos.

  2. Nueva claseUser

    public class User
    {
        public int Id { get; set; }
    
        public string Name { get; set; }
    
        public uint Gender { get; set; }
    
        public DateTime BirthDay { get; set; }
    
        public DateTime CreationTime { get; set; }
    
        public User()
        {
            this.CreationTime = DateTime.Now;
        }
    }
    
  3. Nuevo contexto de usuarioUserDbContext.cs

    public class UserDbContext : MasaDbContext
    {
        public DbSet<User> User { get; set; }
    
        public UserDbContext(MasaDbContextOptions options) : base(options)
        {
        }
    }
    

    UserDbContextCambie a heritage MasaDbContexty agregue un constructor con un parámetro, el tipo de parámetro es MasaDbContextOptionsCuando hay varios DbContexts en el proyecto, debe cambiarse a heritage MasaDbContext<TDbContext>y el tipo de parámetro del constructor se cambia aMasaDbContext<TDbContext>

  4. Crear una nueva clase AddUserRequestcomo parámetro para agregar un usuario

    public class AddUserRequest
    {
        public string Name { get; set; }
    
        public uint Gender { get; set; }
    
        public DateTime BirthDay { get; set; }
    }
    
  5. Nueva clase HostExtensionspara migrar base de datos (usando CodeFirst)

    public static class HostExtensions
    {
        public static void MigrateDbContext<TContext>(
            this IHost host, Action<TContext, IServiceProvider> seeder) where TContext : DbContext
        {
            using (var scope = host.Services.CreateScope())
            {
                var services = scope.ServiceProvider;
                var context = services.GetRequiredService<TContext>();
                context.Database.EnsureCreated();
                seeder(context, services);
            }
        }
    }
    
  6. Modificar Program.cs, agregar Swaggersoporte

    builder.Services.AddEndpointsApiExplorer();
    builder.Services.AddSwaggerGen();
    
    var app = builder.Build();
    
    app.UseSwagger();
    app.UseSwaggerUI();
    

No es necesario Swaggeragregar, use Swagger solo para probar el servicio de llamadas, Postmano también se pueden usar otras herramientas Http

  1. Modificar Program.cs, agregar contexto de usuario (énfasis)

    builder.Services.AddMasaDbContext<UserDbContext>(options => 
    {
      options.Builder = (_, dbContextOptionsBuilder) => dbContextOptionsBuilder.UseInMemoryDatabase("test")
    });
    
  2. Modificado Program.cspara que el proyecto sea compatible con CodeFirst.

    app.MigrateDbContext<UserDbContext>((context, services) =>
    {
    });
    

    No se requiere CodeFirst y no es necesario agregar una base de datos que no admita la generación de código.

  3. probar MasaDbContext, modificarProgram.cs

    app.MapPost("/add", (UserDbContext dbContext, [FromBody] AddUserRequest request) =>
    {
        dbContext.Set<User>().Add(new User()
        {
            Name = request.Name,
            Gender = request.Gender,
            BirthDay = request.BirthDay
        });
        dbContext.SaveChanges();
    });
    
    app.MapGet("/list", (UserDbContext dbContext) =>
    {
        return dbContext.Set<User>().ToList();
    });
    

    Ejecute el proyecto usted mismo add, cree un nuevo usuario después de la ejecución y luego ejecútelo listpara obtener más de un dato de usuario, lo que prueba que el MasaDbContextuso es correcto

Cómo usar la eliminación suave

  1. seleccionar Assignment.MasaEntityFrameworke instalarMasa.Contrib.Data.Contracts.EF

    dotnet add package Masa.Contrib.Data.Contracts.EF --version 0.4.0-rc.4
    
  2. Modifique la clase Usere implemente ISoftDelete, el código se cambia a:

    public class User : ISoftDelete//重点:改为实现ISoftDelete
    {
        public int Id { get; set; }
    
        public string Name { get; set; }
    
        public uint Gender { get; set; }
    
        public DateTime BirthDay { get; set; }
    
        public DateTime CreationTime { get; set; }
    
        public bool IsDeleted { get; private set; }
    
        public User()
        {
            this.CreationTime = DateTime.Now;
        }
    }
    

    Agregue implementación ISoftDeletey IsDeletedagregue soporte de conjunto para propiedades (puede ser un conjunto privado;)

  3. Modificar Program.csy habilitar el filtrado de datos

    builder.Services.AddMasaDbContext<UserDbContext>(options =>
    {
        options.Builder = (_, dbContextOptionsBuilder) => dbContextOptionsBuilder.UseInMemoryDatabase("test");
        options.UseFilter();//启用数据过滤,完整写法:options.UseFilter(filterOptions => filterOptions.EnableSoftDelete = true);
    });
    
  4. Probar si la eliminación temporal fue exitosa

  • Modificar Program.cs, agregar método de eliminación

    app.MapDelete("/delete", (UserDbContext dbContext, int id) =>
    {
        var user = dbContext.Set<User>().First(u => u.Id == id);
        dbContext.Set<User>().Remove(user);
        dbContext.SaveChanges();
    });
    

Finalmente, primero llame al addmétodo para crear un usuario, luego llame listal método para obtener una lista de todos los usuarios y recupere cualquier información de identificación, luego llame al deletemétodo para eliminar al usuario y finalmente llame listal método para verificar si la identificación recuperada existe . , para verificar el software Si la eliminación es válida.

Cómo deshabilitar temporalmente el filtrado de eliminación temporal

En la consulta predeterminada, los datos que se marcaron como eliminados se filtrarán y ya no se consultarán, pero también hay algunos escenarios en los que es necesario consultar todos los datos, en cuyo caso se requiere el filtrado de datos.IDataFilter

  1. Método agregado Allpara consultar todos los datos (incluidos los datos marcados para su eliminación)

    app.MapGet("/all", (UserDbContext dbContext, [FromServices] IDataFilter dataFilter) =>
    {
        //通过DI获取到IDataFilter,并调用其Disable方法可临时禁用ISoftDelete条件过滤
        using (dataFilter.Disable<ISoftDelete>())
        {
            return dbContext.Set<User>().ToList();
        }
    });
    
  2. Vuelva a ejecutar el proyecto y repita los pasos de verificación de eliminación temporal para asegurarse de que listno se pueda acceder a los datos a través del método

    El motivo para ejecutar repetidamente el paso de eliminación temporal de verificación es que este ejemplo usa una base de datos en memoria. Después de detener el proyecto, se vaciarán todos los datos. La nueva ejecución es para asegurarse de que los datos existen y solo se marcan para su eliminación. .

  3. Ejecute el allmétodo, obtenga todos los datos y verifique si existen los datos de usuario correspondientes a la identificación.

Obtenga la cadena de conexión de la base de datos del archivo de configuración

  1. Seleccione el proyecto Assignment.MasaEntityFrameworke instaleMasa.Contrib.Data.EntityFrameworkCore.InMemory

    dotnet add package Masa.Contrib.Data.EntityFrameworkCore.InMemory --version 0.4.0-rc.4
    

    Instale el paquete de base de datos correspondiente según sea necesario, como: Masa.Contrib.Data.EntityFrameworkCore.SqlServer(SqlServer), Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql(MySql proporcionado por Pomelo), Masa.Contrib.Data.EntityFrameworkCore.Oracle(Oracle), etc.

  2. Modifique Program.cs, ajuste la configuración de contexto de agregar usuario a:

    builder.Services.AddMasaDbContext<UserDbContext>(options => options.UseInMemoryDatabase().UseFilter());
    
  3. Modifique appsettings.json, aumente la cadena de conexión de la base de datos del usuario:

    {
      "ConnectionStrings": {
        "DefaultConnection": "test"//更换为指定的数据库连接字符串
      }
    }
    
  4. Modifique Program.cs, agregue databaseun método, verifique que la base de datos actual seatest

    app.MapGet("/database", (UserDbContext dbContext) =>
    {
        var field = typeof(MasaDbContext).GetField("Options", BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic)!;
        var masaDbContextOptions = field.GetValue(dbContext) as MasaDbContextOptions;
        foreach (var dbContextOptionsExtension in masaDbContextOptions!.Extensions)
        {
            if (dbContextOptionsExtension is InMemoryOptionsExtension memoryOptionsExtension)
            {
                return memoryOptionsExtension.StoreName;
            }
        }
    
        return "";
    });
    

Última visita http://localhost:5002/databasepara verificar si el nombre de la base de datos actual es el mismo que el nombre de la base de datos modificadaVerifique que la base de datos sea de prueba

problema comun

  • ¿Cómo cambiar el nodo de configuración de lectura predeterminado?
  1. Modifique el contexto del usuario UserDbContexty agregue ConnectionStringNamecaracterísticas:

    [ConnectionStringName("User")]//自定义节点名
    public class UserDbContext : MasaDbContext
    {
        public DbSet<User> User { get; set; }
    
        public UserDbContext(MasaDbContextOptions options) : base(options)
        {
        }
    }
    
  2. Cambio de configuracionappsettings.json

    {
      "ConnectionStrings": {
        "User": "test"//改为从User节点读取数据库连接字符串
      }
    }
    
  • ¿Se admite obtener la cadena de conexión de la base de datos desde otro lugar que no sea el archivo de configuración?

Actualmente hay dos formas de cambiar la cadena de conexión de la base de datos.

Método 1: modificar Program.csy eliminar appsettings.jsonla configuración de la cadena de conexión de la base de datos

  1. RevisarProgram.cs

    builder.Services.Configure<MasaDbConnectionOptions>(option =>
    {
        option.ConnectionStrings = new ConnectionStrings(new List<KeyValuePair<string, string>>()
        {
            new("User", "test2")//其中键为节点名,与ConnectionStringName特性的Name值保持一致即可,如果未指定ConnectionStringName,则应该为DefaultConnection,值为数据库连接字符串
        });
    });
    
  2. Modificar appsettings.jsonconfiguración

    //  "ConnectionStrings": {
    //    "User": "test"
    //  },
    
  3. Llame databaseal método para verificar si la base de datos actual estest2

Verifique que la base de datos sea test2

Método 2: anular la implementación de IConnectionStringProvidersum IDbConnectionStringProvidery agregar a DI

  1. Nueva claseCustomizeConnectionStringProvider

    public class CustomizeConnectionStringProvider : IConnectionStringProvider
    {
        public Task<string> GetConnectionStringAsync(string name = "DefaultConnection") => Task.FromResult    (GetConnectionString(name));
    
        public string GetConnectionString(string name = "DefaultConnection") => "test3";
    }
    
  2. Nueva claseCustomizeDbConnectionStringProvider

    public class CustomizeDbConnectionStringProvider : IDbConnectionStringProvider
    {
        public List<MasaDbContextConfigurationOptions> DbContextOptionsList { get; } = new()
        {
            new MasaDbContextConfigurationOptions("test3")
        };
    }
    
  3. RevisarProgram.cs

    builder.Services.AddSingleton<IConnectionStringProvider,CustomizeConnectionStringProvider>();
    builder.Services.AddSingleton<IDbConnectionStringProvider,CustomizeDbConnectionStringProvider>();
    
  4. Llame databaseal método para verificar si la base de datos actual estest3 Verifique que la base de datos sea test3

Resumir

Este artículo explica principalmente el MasaDbContextuso básico y cómo usar la eliminación temporal y el filtrado de datos. En el siguiente artículo, explicaremos MasaDbContextcómo implementar la eliminación temporal y el filtrado de datos, y cómo usar la base de datos sin especificar el carácter de enlace de la base de datos mencionado en este artículo. ¿Cómo se implementa el tiempo de cadena?

Código fuente de este capítulo

Tarea05

https://github.com/zhenlei520/MasaFramework.Practice

dirección de fuente abierta

MASA.BuildingBlocks: https://github.com/masastack/MASA.BuildingBlocks

MASA.Contrib: https://github.com/masastack/MASA.Contrib

MASA.Utils: https://github.com/masastack/MASA.Utils

MASA.EShop: https://github.com/masalabs/MASA.EShop

MASA.Blazor: https://github.com/BlazorComponent/MASA.Blazor

Si está interesado en nuestro Marco MASA, ya sea contribución de código, uso o emisión, contáctenos

16373211753064.png

{{o.nombre}}
{{m.nombre}}

Supongo que te gusta

Origin my.oschina.net/u/5447363/blog/5549631
Recomendado
Clasificación