2017-02-20 126 views
23

正在移植到.NET核心的我的應用程序將使用帶有SQLite的新EF核心。我想在應用第一次運行時自動創建數據庫和表結構。按照EF核心文檔,這是使用手動命令完成在實體框架核心中自動創建數據庫

dotnet ef migrations add MyFirstMigration 

dotnet ef database update 

但是我不希望最終用戶輸入這些命令,並希望有應用程序創建和設置第一次使用的數據庫。對於EF 6,功能類似於

Database.SetInitializer(new CreateDatabaseIfNotExists<MyContext>()); 

但是在EF內核中,這些似乎並不存在。我無法找到任何與EF內核相同的示例或文檔,並且在EF內核文檔的缺失功能列表中未提及。我已經設置了模型類,因此我可以根據模型編寫一些代碼來初始化數據庫,但如果框架自動執行此操作,會更容易。我不想自動構建模型或遷移,只需在新數據庫上創建表結構。

我在這裏丟失了什麼,或者在EF內核中缺少自動創建表格功能?

回答

22

如果您已經創建了遷移,您可以按如下方式在Startup.cs中執行它們。

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
{ 
     using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope()) 
     { 
      var context = serviceScope.ServiceProvider.GetRequiredService<ApplicationDbContext>(); 
      context.Database.Migrate(); 
     } 

     ... 

這將使用您添加的遷移創建數據庫和表。

如果你不使用實體框架遷移,而是隻需要你的DbContext模型創建的,正是因爲它是在第一次運行你的上下文類,那麼你可以使用:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
{ 
     using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope()) 
     { 
      var context = serviceScope.ServiceProvider.GetRequiredService<ApplicationDbContext>(); 
      context.Database.EnsureCreated(); 
     } 

     ... 

相反。

如果您需要刪除數據庫,確保它的創建之前,請致電:

  context.Database.EnsureDeleted(); 

你打電話EnsureCreated()就在

摘自:http://docs.identityserver.io/en/release/quickstarts/8_entity_framework.html?highlight=entity

+0

我依然很漂亮EF是新的,我使用當前數據庫文件創建了使用EF 6代碼首先「從數據庫創建」從Visual Studio中定義數據結構的類。然後,我將這些內容剪切/粘貼到新的dotnet內核VS解決方案中 - 所以我想這些都不是遷移。這是否意味着我必須在上面的代碼可以使用之前創建一個遷移文件? – deandob

+0

我真的很抱歉,我沒有在我的答案錯誤,如果你不使用遷移,可以使用命令context.Database.EnsureCreated()/ EnsureDeleted(),在https://blogs.msdn.microsoft更多細節。 com/dotnet/2016/09/29/Implement-seeding-custom-conventions-and-interceptors-in-ef-core-1-0/ –

+0

是的,很有幫助,謝謝。 – deandob

7

我的回答與裏卡多的回答非常相似,但我覺得我的方法更簡單一點,因爲他的功能有如此之多,以至於我甚至不知道它是如何在較低的水平上工作。

因此,對於那些誰想要爲你,你知道什麼是引擎蓋下發生創建數據庫的簡單和乾淨的解決方案,這是給你:

public Startup(IHostingEnvironment env) 
{ 
    using (var client = new TargetsContext()) 
    { 
     client.Database.EnsureCreated(); 
    } 
} 

這幾乎意味着中(在這種情況下,我的名稱爲TargetsContext),您可以使用DbContext的實例來確保在您的應用程序中運行Startup.cs時,將創建在類中定義的表。

+2

正如從信息[這裏](https://github.com/aspnet/EntityFrameworkCore/issues/3160):'EnsureCreated'完全繞過遷移和只爲你創建架構,你不能遷移混合此。 'EnsureCreated'專爲測試或快速原型設計而設計,您可以隨時刪除和重新創建數據庫。如果您正在使用遷移並希望將它們自動應用於應用程序啓動,那麼您可以使用'context.Database.Migrate()'來代替。 –

+0

@ThomasSchneiter哦,很酷!感謝那!我不知道。 –

+0

這回答我的困惑,爲什麼我的連接字符串不工作... :( 因此,數據庫不會自動創建,你必須指定我在我的DbContext構造函數中完成的Database.EnsureCreated()。 非常感謝你,拯救我從3天兩難境地。X_X – pampi

1

如果您尚未創建遷移,有2個選項

1。從應用的主要創建數據庫和表:

var context = services.GetRequiredService<YourRepository>(); 
context.Database.EnsureCreated(); 

2.創建表,如果數據庫已經存在:

var context = services.GetRequiredService<YourRepository>(); 
context.Database.EnsureCreated(); 
RelationalDatabaseCreator databaseCreator = 
(RelationalDatabaseCreator)context.Database.GetService<IDatabaseCreator>(); 
databaseCreator.CreateTables(); 

由於布比族的answer

2

如果你通過參數上下文在Startup.cs配置列表中,您可以改爲執行此操作:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, LoggerFactory loggerFactory, 
    ApplicationDbContext context) 
{ 
     context.Database.Migrate(); 
     ... 
相關問題