2017-09-01 106 views
1

我有一个简单的DbContext,MyDbContext,与2个DbSets:不EF核心迁移调用Startup.Configure()上附加迁移

public DbSet<User> Users { get; set; } 
public DbSet<Privilege> Privileges { get; set; } 

当我跑PM控制台添加迁移,已成功生成迁移。然后我添加了代码来为Privileges表种子。我添加的代码是在Startup.Configure():

using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope()) 
{ 
    serviceScope.ServiceProvider.GetService<OneSourceDbContext>().Database.Migrate(); 
    serviceScope.ServiceProvider.GetService<OneSourceDbContext>().EnsureSeedData(); 
} 

EnsureSeedData是一个扩展方法,看起来像这样:

public static void EnsureSeedData(this OneSourceDbContext context) 
{ 
    if (!context.Database.GetPendingMigrations().Any()) 
    { 
     if (!context.Privileges.Any()) 
     { 
       context.Privileges.Add(new Models.Privilege { Name = "Add/Edit" }); 
       context.SaveChanges(); 
      } 
     } 
    } 

添加该代码后,我删除所有迁移,并试图再次产生,但这次它说特权是无效的对象。此外,即使我尚未运行该项目并且尚未调用update-database,也会生成一个空的数据库。如果我在Configure()方法中注释EnsureSeedData,则会生成迁移。

我认为2线Database.Migrate()和EnsureSeedData()当我运行该项目将只被调用,但似乎这里面检查EnsureSeedData()

!context.Privileges.Any() 

导致迁移失败。启动时添加迁移是否确实调用了Configure()?它令人困惑,因为我只想创建迁移文件,为什么它运行(或似乎运行)EnsureSeedData()?

回答

2

Startup.Configure()应该只包含配置请求管道的代码。任何应用程序启动/初始化代码应该在Program.Main()

+0

好的,但我的问题是为什么当我运行添加迁移时它会被调用?当您调用add-migration命令时,Startup.Configure()中的所有代码是否都会运行? –

+1

如果存在'Program.BuildWebHost()',EF核心工具将调用它来访问应用程序服务提供者。是的,这(不幸的是)会调用'Startup.Configure()'作为一个副作用。解决方法是删除它并使用'IDesignTimeDbContextFactory'。 – bricelam