前言
寫 Library 有時候會用到 database, 會想用 EF 來維護.
比如 Identity, IdentityServer, OpenIddict, 這些 Library 都有使用到 EF.
雖然大家都用 EF, 但它們使用的手法都不太一樣哦.
這篇就來研究一下, 寫 Library 的時候怎麼去使用 EF.
主要參考
相關 Class Library EF Core 的文章
.NET Core — Using Entity Framework Core in a separate Project
Design-time DbContext Creation
A library to run your business logic when using Entity Framework Core
Using EF Core in a Separate Class Library
Using EF Core in a Separate Class Library project
4 種手法
不要問我爲什麼有這麼多 pattern. 我也想知道.
繼承方式
Identity 的做法是用繼承, ApplicationDbContext 繼承 IdentityDbContext
我不太欣賞這種方式 (就不多介紹了). 但是不只 identity 這樣用哦, 有些 library 也是用這個方式
多個 DbContext
IdentityServer 用的方式是多個 DbContext, 出來的 Migrations folder 長這樣
我覺得這個方案挺不錯的, 分得很開.
首先, Library 定義好 LibraryDbContext, Entity 等
然後 Application startup,cs
var assemblyName = typeof(Program).GetTypeInfo().Assembly.GetName().Name; builder.Services.AddDbContext<LibraryDbContext>(options => options.UseSqlServer(connectionString, o => o.MigrationsAssembly(assemblyName)) );
這裏只是寫個 demo 我就沒有封裝太美了, 關鍵就是那個 options.UseSqlServer 要讓 Application 負責就可以了.
還有一點就是一定要配上 MigrationsAssembly.
ReplaceService IModelCustomizer
OpenIddict 用的是 ReplaceService
然後
然後
這個方案我也是不太喜歡 (就不多介紹了), 要知道 ReplaceService 只能用一次丫, 你用了其它 Library 也要用就完了.
關於這個方案也可以看這篇 Using Entity Framework Core IModelCustomizer to target multiple data stores
還有它的 limitation
ModelBuilder 擴展
這個是我在 AutoHistory 插件看見的
攔截到了, modelBuilder 就可以用來做 config 了
雖然寫不了 DbSet 這種東西, 但是不要緊.
public DbSet<Product> Products => Set<Product>();
調用的時候可以用泛型 Type
我覺得這個方案算是最簡單的了.