[英]Seeding Data with Entity Framework 3.0 with Model or Migration?
[英]Establish auto migration and seeding without spoiling Entity Framework toolchain
不幸的是實體Framwork核心不支持IDatabaseInitializer
小號了:所以沒有DropCreateDatabaseAlways.Seed()
和DropCreateDatabaseIfModelChanges.Seed()
:-(
因此人們在那里寫了很多東西來:
DbContext
的具體實例的幫助下應用種子數據。 我在Startup.Configure
的末尾提出了以下幾行內容:我在其中注入了IApplicationBuilder app
和IHostingEnvironment env
:
using (var scope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
using (var context = scope.ServiceProvider.GetService<MyDbContext>())
{
var hasPendingMigrations = context.Database.GetPendingMigrations().Any();
if (hasPendingMigrations) {
var needsSeeding = !context.Database.GetAppliedMigrations().Any(); // No migration yet (no database or it's empty).
context.Database.Migrate(); // Create/update schema (creates database if necessary).
if (needsSeeding) {
Seed(context);
if (env.IsDevelopment()) {
SeedWithDummyData(context);
}
}
}
}
}
但是將這些行放在Startup.Configure
的末尾會破壞Entity Framework工具鏈:
PM> Add-Migration MyMigration
PM> Update-Datebase
以及:
PM> Update-Datebase NameOfPreviousMigration
PM> Remove-Migration
這些Commandlet正在使用Program.BuildWebHost()
方法來調用我的Startup
和Startup.ConfigureServices()
以及Startup.Configure()
(即使不需要: https : //github.com/aspnet/EntityFrameworkCore/issues/ 9076 )。 如果我打電話給Remove-Migration
更糟了: Remove-Migration
→ Startup.Configure()
→遷移和種子(數據庫處於最新遷移狀態=無法刪除遷移)→錯誤:
遷移“ 20170914084432_MyMigration”已應用於數據庫。 還原它,然后再試一次。 如果已將遷移應用於其他數據庫,請考慮使用新的遷移還原其更改。
簡而言之,如何將Migrate&Seed東西從工具鏈中移出,分別告訴我Startup.Configure()
的工具鏈手?
請記住:我不喜歡使用IDesignTimeDbContextFactory
因為...
IConfiguration
實例來檢索連接字符串。 ConfigurationBuilder
也是多余的( 從appsettings.json獲取ConnectionString而不是在.NET Core 2.0 App中進行硬編碼 )。 特別是在EF Core 2.0中,它非常麻煩且容易出錯,因為您始終必須模仿WebHost.CreateDefaultBuilder()
。 IDesignTimeDbContextFactory
,也仍然會調用Program.BuildWebHost()
並最終調用Startup.ConfigureServices()
(並且https://github.com/aspnet/EntityFrameworkCore/issues/9076#issuecomment-313278753是一個很差的解決方法!)。 經過數小時的猜測和失敗,我放棄了Startup
課! 因此,我現在將RuntimeStartup
用於運行時,並將幾乎空的Startup
用於所有設計時任務(支架和遷移):
public class Program
{
public static void Main(string[] args)
{
WebHost.CreateDefaultBuilder(args)
.UseStartup<RuntimeStartup>()
.Build()
.Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
為什么這么復雜?
Startup
類以將MyDbContext
注冊為服務。 (當前)無法指向另一個課程! 如果嘗試,您將獲得:
腳手架無法編輯啟動類以使用依賴注入來注冊新的上下文。 確保其中包含一個Startup類以及一個ConfigureServices方法和Configuration屬性。
BuildWebHost
方法。 因此,您也需要在此處使用Startup
。 否則,您會收到以下誤導性消息:
沒有為此對象定義無參數構造函數。
BuildWebHost
方法來獲取啟動類(與腳手架相同)。 結論:
因此,如果您不想在每次添加新的Controller或添加/刪除遷移時都調用遷移和播種,則必須提供一個精益的Startup
類並將(運行時)內容放到其他地方!
由您決定在設計時和運行時啟動時重用ConfigureServices()
方法來創建基類。 (請記住,腳手架在修改Startup
基本類型時總是會失敗。但是據我所知,只有將MyDbContext
注冊為服務才會發生。這應該是可管理的。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.