前言
Masa
提供了基于EntityFramework
的数据集成,并提供了数据过滤与软删除的性能,上面咱们将介绍如何应用它?
MasaDbContext入门
- 装置.Net 6.0
新建ASP.NET Core 空我的项目
Assignment.MasaEntityFramework
,并装置Masa.Contrib.Data.EntityFrameworkCore
、Swashbuckle.AspNetCore
、Microsoft.EntityFrameworkCore.InMemory
、Microsoft.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创立数据库新建类
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; }}
新建用户上下文
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>
新建类
AddUserRequest
作为增加用户的参数public class AddUserRequest{ public string Name { get; set; } public uint Gender { get; set; } public DateTime BirthDay { get; set; }}
新建类
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); } }}
批改
Program.cs
,新增Swagger
反对builder.Services.AddEndpointsApiExplorer();builder.Services.AddSwaggerGen();var app = builder.Build();app.UseSwagger();app.UseSwaggerUI();
不须要Swagger
可不增加,应用Swagger仅仅是为了测试调用服务,应用Postman
或其余的Http工具也能够
批改
Program.cs
,增加用户上下文(重点)builder.Services.AddMasaDbContext<UserDbContext>(options => { options.Builder = (_, dbContextOptionsBuilder) => dbContextOptionsBuilder.UseInMemoryDatabase("test")});
批改
Program.cs
,使我的项目反对CodeFirstapp.MigrateDbContext<UserDbContext>((context, services) =>{});
不须要CodeFirst,不反对代码生成数据库可不增加
测试
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
应用无误
如何应用软删除
选中
Assignment.MasaEntityFramework
并装置Masa.Contrib.Data.Contracts.EF
dotnet add package Masa.Contrib.Data.Contracts.EF --version 0.4.0-rc.4
批改类
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;)批改
Program.cs
,并启用数据过滤builder.Services.AddMasaDbContext<UserDbContext>(options =>{ options.Builder = (_, dbContextOptionsBuilder) => dbContextOptionsBuilder.UseInMemoryDatabase("test"); options.UseFilter();//启用数据过滤,残缺写法:options.UseFilter(filterOptions => filterOptions.EnableSoftDelete = true);});
- 测试软删除是否胜利
批改
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
新增
All
办法用于查问所有的数据(蕴含标记曾经删除的数据)app.MapGet("/all", (UserDbContext dbContext, [FromServices] IDataFilter dataFilter) =>{ //通过DI获取到IDataFilter,并调用其Disable办法可长期禁用ISoftDelete条件过滤 using (dataFilter.Disable<ISoftDelete>()) { return dbContext.Set<User>().ToList(); }});
从新运行我的项目,反复执行验证软删除步骤,确保通过
list
办法拜访不到数据反复运行验证软删除步骤的起因在于本示例应用的是内存数据库,我的项目进行后,所有数据都会被清空,从新执行是为了确保数据存在,仅被标记为删除
- 执行
all
办法,获取所有的数据,查看id所对应的用户数据是否存在
从配置文件中获取数据库连贯字符串
选中我的项目
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)等批改
Program.cs
,调整增加用户上下文配置为:builder.Services.AddMasaDbContext<UserDbContext>(options => options.UseInMemoryDatabase().UseFilter());
批改
appsettings.json
,减少用户数据库连贯字符串:{ "ConnectionStrings": { "DefaultConnection": "test"//更换为指定的数据库连贯字符串 }}
批改
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
,验证以后的数据库名称与批改后的数据库名称是否统一
常见问题
- 如何更改默认读取的配置节点?
批改用户上下文
UserDbContext
并减少ConnectionStringName
个性:[ConnectionStringName("User")]//自定义节点名public class UserDbContext : MasaDbContext{ public DbSet<User> User { get; set; } public UserDbContext(MasaDbContextOptions options) : base(options) { }}
批改配置
appsettings.json
{ "ConnectionStrings": { "User": "test"//改为从User节点读取数据库连贯字符串 }}
- 除了从配置文件中获取,还反对从其余中央获取数据库连贯字符串吗?
目前有两种方法能够更改数据库连贯字符串。
办法1: 批改Program.cs
,并删除appsettings.json
数据库连贯字符串的配置
批改
Program.cs
builder.Services.Configure<MasaDbConnectionOptions>(option =>{ option.ConnectionStrings = new ConnectionStrings(new List<KeyValuePair<string, string>>() { new("User", "test2")//其中键为节点名,与ConnectionStringName个性的Name值保持一致即可,如果未指定ConnectionStringName,则应该为DefaultConnection,值为数据库连贯字符串 });});
批改
appsettings.json
配置// "ConnectionStrings": {// "User": "test"// },
- 调用
database
办法,验证以后数据库是否为test2
办法2: 重写IConnectionStringProvider
和IDbConnectionStringProvider
的实现并增加到DI中
新建类
CustomizeConnectionStringProvider
public class CustomizeConnectionStringProvider : IConnectionStringProvider{ public Task<string> GetConnectionStringAsync(string name = "DefaultConnection") => Task.FromResult (GetConnectionString(name)); public string GetConnectionString(string name = "DefaultConnection") => "test3";}
新建类
CustomizeDbConnectionStringProvider
public class CustomizeDbConnectionStringProvider : IDbConnectionStringProvider{ public List<MasaDbContextConfigurationOptions> DbContextOptionsList { get; } = new() { new MasaDbContextConfigurationOptions("test3") };}
批改
Program.cs
builder.Services.AddSingleton<IConnectionStringProvider,CustomizeConnectionStringProvider>();builder.Services.AddSingleton<IDbConnectionStringProvider,CustomizeDbConnectionStringProvider>();
- 调用
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,欢送分割咱们