2017-02-20 177 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(); 
     ... 
相关问题