Masa
提供了基於EntityFramework
的資料整合,並提供了資料過濾與軟刪除的功能,下面我們將介紹如何使用它?
新建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
,使專案支援CodeFirst
app.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/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,歡迎聯絡我們
本文來自部落格園,作者:磊_磊,轉載請註明原文連結:https://www.cnblogs.com/zhenlei520/p/16325414.html
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連結,否則保留追究法律責任的權利