前言
Masa提供了基於EntityFramework的數據集成,並提供了數據過濾與軟删除的功能,下面我們將介紹如何使用它?
MasaDbContext入門
- 安裝.Net 6.0
新建ASP.NET Core 空項目
Assignment.MasaEntityFramework,並安裝Masa.Contrib.Data.EntityFrameworkCore、Swashbuckle.AspNetCore、Microsoft.EntityFrameworkCore.InMemory、Microsoft.EntityFrameworkCore.Toolsdotnet 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創建數據庫新建類
Userpublic 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.cspublic 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.csapp.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.EFdotnet 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.InMemorydotnet 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方法,驗證當前數據庫是testapp.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.csbuilder.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中
新建類
CustomizeConnectionStringProviderpublic class CustomizeConnectionStringProvider : IConnectionStringProvider { public Task<string> GetConnectionStringAsync(string name = "DefaultConnection") => Task.FromResult (GetConnectionString(name)); public string GetConnectionString(string name = "DefaultConnection") => "test3"; }新建類
CustomizeDbConnectionStringProviderpublic class CustomizeDbConnectionStringProvider : IDbConnectionStringProvider { public List<MasaDbContextConfigurationOptions> DbContextOptionsList { get; } = new() { new MasaDbContextConfigurationOptions("test3") }; }修改
Program.csbuilder.Services.AddSingleton<IConnectionStringProvider,CustomizeConnectionStringProvider>(); builder.Services.AddSingleton<IDbConnectionStringProvider,CustomizeDbConnectionStringProvider>();調用
database方法,驗證當前數據庫是否為test3
總結
本篇文章主要講解了MasaDbContext的基本用法以及軟删除、數據過濾如何使用,下篇文章我們會講解一下MasaDbContext是如何實現軟删除、數據過濾的,以及本篇文章中提到使用數據庫時不指定數據庫鏈接字符串時如何實現的
本章源碼
Assignment05
https://github.com/zhenlei520/MasaFramework.Practice
開源地址
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
如果你對我們的 MASA Framework 感興趣,無論是代碼貢獻、使用、提 Issue,歡迎聯系我們



![18.[stm32] read the ROM of DS18B20 temperature sensor and realize multi-point temperature measurement](/img/e7/4f682814ae899917c8ee981c05edb8.jpg)






