dotnet ef迁移自动化:检测迁移的变化

tik*_*ika 9 asp.net entity-framework entity-framework-core asp.net-core

我使用以下CLI进行数据库迁移:

  1. dotnet ef migrations add <Name-of-Migration>
  2. dotnet ef database update

但是,我正在寻找一种自动发生的方法:当检测到模型中的更改时.

到目前为止,我已经能够通过在Startup.cs中执行以下操作来消除步骤2:

 private void SetupDatabase(IApplicationBuilder app)
    {
        using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
        {
            var context = serviceScope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
            //Migate any pending changes:
            context.Database.Migrate();
        }
    }
Run Code Online (Sandbox Code Playgroud)

这会迁移通过执行创建的任何挂起的更改: dotnet ef migrations add <Name-of-Migration> 但它不会为模型中的任何更改添加迁移.我该如何自动化migrations add

Has*_*san 11

更新:可以从代码中自动生成迁移的第一步,这是我个人不同意的设计决策.它仍然在你的目标EF7,因为我原来说不可能的(它已经从EF7删除它似乎提到这个SO发布以及对本博客文章微软EF团队的一员伊万在评论中提到),但测试在Martin回复后的EF6中.第二步可以自动化,因为你已经发现,所以我不会再次重现它.

第一步的步骤如下(在带有EF6的ASP.net MVC Web应用程序中):

  1. 在您的项目中(应该已经与某些模型一起运行并处于一致状态),转到包管理器控制台并运行Enable-Migrations –EnableAutomaticMigrations.如果您的应用程序具有单个数据库上下文,则它也在那里应用了更改.
  2. 现在转到现有模型并在那里添加一个新字段,例如 public String TestField { get; set; }
  3. 当代码第一次自动迁移打开时,您不需要Add-Migration再次运行命令(希望,正如我在本答案的后面部分所指出的那样),您只需运行Update-Database并且应该更新数据库,以使您的应用程序正常运行.

为什么自动模型更改监视自动生成和更新数据库可能会适得其反(在我的拙见和MSDN页面中):

  • 根据MSDN,自动迁移在更改字段重命名时不起作用.
  • 如果添加了原始字段类型,则需要考虑现有数据,您应该考虑在此方案中进行手动迁移.
  • 您可以散布自动和基于代码的迁移,但在团队开发方案中不建议这样做.如果您是使用源代码管理的开发人员团队的一员,则应使用纯自动迁移或纯粹基于代码的迁移.鉴于自动迁移的限制,MSDN建议在团队环境中使用基于代码的迁移.
  • 很好地确认模型更改是故意的,并且在进行更改时不是某些剩余代码的结果,可能发生的事情以及自动化整个过程可能会将这些更改传递给DB.
  • 由于某些数据限制或类似问题,生成的迁移并不总是优化和/或失败,因此应进行审核.
  • 在某些情况下,当迁移处理的数据量很大时,甚至更新数据库也会暂停生产数据.然后我们必须手动远程运行它并重启服务器.

上述内容可能并不适用于所有人,但我认为应该分享我同意不将迁移生成和应用程序自动化应用于DB的设计决策的原因.

考虑启用自动迁移的每个人都应该确保阅读MSDN页面以获取更多示例和缺点.


Mar*_*ans 6

实体框架4.3引入了自动迁移.

虽然我同意哈桑的答案,说明这可能非常棘手,但这个选项确实存在.

这是一个简短的简历:

  1. 启用迁移时,必须在程序包管理器控制台中提供参数:

enable-migrations -EnableAutomaticMigration:$ true

  1. 将自动生成Configuration类:

    public Configuration()
    {
        AutomaticMigrationsEnabled = true;
    
        //Set this parameter to true if you want to let auto-migration delete data when a property is removed from an entity.
        //Not setting this will result in an exception when migration should remove a column.
        AutomaticMigrationDataLossAllowed = true;
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 在Context类中设置DB Initializer

    Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyDBContext, MyConfigurationClass>("MyConnectionString"));
    
    Run Code Online (Sandbox Code Playgroud)

你去,改变你的模型,看看变化......

我仍然不确定我会使用它,因为当我这样说时我希望我的数据库改变...