前言

Masa提供了基于EntityFramework的数据集成,并提供了数据过滤与软删除的性能,上面咱们将介绍如何应用它?

MasaDbContext入门

  • 装置.Net 6.0
  1. 新建ASP.NET Core 空我的项目Assignment.MasaEntityFramework,并装置Masa.Contrib.Data.EntityFrameworkCoreSwashbuckle.AspNetCoreMicrosoft.EntityFrameworkCore.InMemoryMicrosoft.EntityFrameworkCore.Tools

    dotnet add package Masa.Contrib.Data.EntityFrameworkCore --version 0.4.0-rc.4dotnet add package Swashbuckle.AspNetCore --version 6.2.3dotnet add package Microsoft.EntityFrameworkCore.InMemory --version 6.0.5dotnet add package Microsoft.EntityFrameworkCore.Tools --version 6.0.5
    装置Swashbuckle.AspNetCore是为了不便通过Swagger来操作服务
    装置Microsoft.EntityFrameworkCore.InMemory是为了不便,因而应用内存数据库,如果须要应用其余数据库,请自行装置对应的包
    装置Microsoft.EntityFrameworkCore.Tools是为了应用CodeFirst创立数据库
  2. 新建类User

    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. 新建用户上下文UserDbContext.cs

    public class UserDbContext : MasaDbContext{    public DbSet<User> User { get; set; }    public UserDbContext(MasaDbContextOptions options) : base(options)    {    }}
    UserDbContext改为继承MasaDbContext, 并新增一个参数的构造函数,参数类型为MasaDbContextOptions
    当我的项目中存在多个DbContext时,须要改为继承MasaDbContext<TDbContext>,结构函数参数类型改为MasaDbContext<TDbContext>
  4. 新建类AddUserRequest作为增加用户的参数

    public class AddUserRequest{    public string Name { get; set; }    public uint Gender { get; set; }    public DateTime BirthDay { get; set; }}
  5. 新建类HostExtensions用于迁徙数据库(应用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. 批改Program.cs,新增Swagger反对

    builder.Services.AddEndpointsApiExplorer();builder.Services.AddSwaggerGen();var app = builder.Build();app.UseSwagger();app.UseSwaggerUI();
不须要Swagger可不增加,应用Swagger仅仅是为了测试调用服务,应用Postman或其余的Http工具也能够
  1. 批改Program.cs,增加用户上下文(重点)

    builder.Services.AddMasaDbContext<UserDbContext>(options => {  options.Builder = (_, dbContextOptionsBuilder) => dbContextOptionsBuilder.UseInMemoryDatabase("test")});
  2. 批改Program.cs,使我的项目反对CodeFirst

    app.MigrateDbContext<UserDbContext>((context, services) =>{});
    不须要CodeFirst,不反对代码生成数据库可不增加
  3. 测试MasaDbContext,批改Program.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();});
    自行运行我的项目,执行add后创立一个新的用户,之后执行list失去一个以上的用户数据,则证实MasaDbContext应用无误

如何应用软删除

  1. 选中Assignment.MasaEntityFramework并装置Masa.Contrib.Data.Contracts.EF

    dotnet add package Masa.Contrib.Data.Contracts.EF --version 0.4.0-rc.4
  2. 批改类User,并实现ISoftDelete,代码改为:

    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;    }}
    减少实现ISoftDelete,并为IsDeleted属性增加set反对(能够是private set;)
  3. 批改Program.cs,并启用数据过滤

    builder.Services.AddMasaDbContext<UserDbContext>(options =>{    options.Builder = (_, dbContextOptionsBuilder) => dbContextOptionsBuilder.UseInMemoryDatabase("test");    options.UseFilter();//启用数据过滤,残缺写法:options.UseFilter(filterOptions => filterOptions.EnableSoftDelete = true);});
  4. 测试软删除是否胜利
  • 批改Program.cs,新增删除办法

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

最初,先调用add办法创立用户后,之后再调用list办法获取所有的用户列表,并取出任意一条id信息,而后再调用delete办法删除用户,最初再调用list办法,查看取出的id是否存在,以此来验证软删除是否无效。

如何长期禁用软删除过滤

默认查问中会将标记曾经被删除的数据过滤不再进行查问,但也有一些场景须要查问所有的数据,此时就须要用到数据过滤IDataFilter

  1. 新增All办法用于查问所有的数据(蕴含标记曾经删除的数据)

    app.MapGet("/all", (UserDbContext dbContext, [FromServices] IDataFilter dataFilter) =>{    //通过DI获取到IDataFilter,并调用其Disable办法可长期禁用ISoftDelete条件过滤    using (dataFilter.Disable<ISoftDelete>())    {        return dbContext.Set<User>().ToList();    }});
  2. 从新运行我的项目,反复执行验证软删除步骤,确保通过list办法拜访不到数据

    反复运行验证软删除步骤的起因在于本示例应用的是内存数据库,我的项目进行后,所有数据都会被清空,从新执行是为了确保数据存在,仅被标记为删除
  3. 执行all办法,获取所有的数据,查看id所对应的用户数据是否存在

从配置文件中获取数据库连贯字符串

  1. 选中我的项目Assignment.MasaEntityFramework,并装置Masa.Contrib.Data.EntityFrameworkCore.InMemory

    dotnet add package Masa.Contrib.Data.EntityFrameworkCore.InMemory --version 0.4.0-rc.4
    依据须要装置对应数据库包即可,如:Masa.Contrib.Data.EntityFrameworkCore.SqlServer (SqlServer)、Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql (Pomelo提供的MySql)、Masa.Contrib.Data.EntityFrameworkCore.Oracle (Oracle)等
  2. 批改Program.cs,调整增加用户上下文配置为:

    builder.Services.AddMasaDbContext<UserDbContext>(options => options.UseInMemoryDatabase().UseFilter());
  3. 批改appsettings.json,减少用户数据库连贯字符串:

    {  "ConnectionStrings": {    "DefaultConnection": "test"//更换为指定的数据库连贯字符串  }}
  4. 批改Program.cs,新增database办法,验证以后数据库是test

    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 "";});

最初拜访http://localhost:5002/database,验证以后的数据库名称与批改后的数据库名称是否统一

常见问题

  • 如何更改默认读取的配置节点?
  1. 批改用户上下文UserDbContext并减少ConnectionStringName个性:

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

    {  "ConnectionStrings": {    "User": "test"//改为从User节点读取数据库连贯字符串  }}
  • 除了从配置文件中获取,还反对从其余中央获取数据库连贯字符串吗?

目前有两种方法能够更改数据库连贯字符串。

办法1: 批改Program.cs,并删除appsettings.json数据库连贯字符串的配置

  1. 批改Program.cs

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

    //  "ConnectionStrings": {//    "User": "test"//  },
  3. 调用database办法,验证以后数据库是否为test2

办法2: 重写IConnectionStringProviderIDbConnectionStringProvider的实现并增加到DI中

  1. 新建类CustomizeConnectionStringProvider

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

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

    builder.Services.AddSingleton<IConnectionStringProvider,CustomizeConnectionStringProvider>();builder.Services.AddSingleton<IDbConnectionStringProvider,CustomizeDbConnectionStringProvider>();
  4. 调用database办法,验证以后数据库是否为test3

总结

本篇文章次要解说了MasaDbContext的根本用法以及软删除、数据过滤如何应用,下篇文章咱们会解说一下MasaDbContext是如何实现软删除、数据过滤的,以及本篇文章中提到应用数据库时不指定数据库链接字符串时如何实现的

本章源码

Assignment05

https://github.com/zhenlei520...

开源地址

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

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

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

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

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

如果你对咱们的 MASA Framework 感兴趣,无论是代码奉献、应用、提 Issue,欢送分割咱们