共计 7393 个字符,预计需要花费 19 分钟才能阅读完成。
前言
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.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
装置
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,欢送分割咱们