Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Entity framework 清理旧实体框架核心迁移的推荐方法_Entity Framework_.net Core_Entity Framework Core - Fatal编程技术网

Entity framework 清理旧实体框架核心迁移的推荐方法

Entity framework 清理旧实体框架核心迁移的推荐方法,entity-framework,.net-core,entity-framework-core,Entity Framework,.net Core,Entity Framework Core,在开发应用程序一段时间后,我们积累了相当多的EFCore数据库迁移。由于EFCore在每次迁移中都会添加整个db模型的快照,所以这段代码会增加很多内容。经过分析,大约80%的编译时间用于迁移(编译+Roslyn分析器) 所以,是时候清理一些旧的迁移了!但是最好的方法是什么呢?似乎没有任何官方的指导 我们不需要任何回滚(我们只需要前滚),这样事情就更简单了。我们确实需要支持从头开始创建数据库,并从最近几次迁移中更新数据库 我所尝试的: 核心选项似乎是删除所有迁移和模型快照,并创建新的初始迁移。虽然

在开发应用程序一段时间后,我们积累了相当多的EFCore数据库迁移。由于EFCore在每次迁移中都会添加整个db模型的快照,所以这段代码会增加很多内容。经过分析,大约80%的编译时间用于迁移(编译+Roslyn分析器)

所以,是时候清理一些旧的迁移了!但是最好的方法是什么呢?似乎没有任何官方的指导

我们不需要任何回滚(我们只需要前滚),这样事情就更简单了。我们确实需要支持从头开始创建数据库,并从最近几次迁移中更新数据库

我所尝试的:

  • 核心选项似乎是删除所有迁移和模型快照,并创建新的初始迁移。虽然这很好,但似乎有点危险。使用这种方法时,我们需要非常小心,数据库模式的每个部分都是代码模型的一部分。例如,我们遇到的一个边缘情况是EFCore还不支持检查约束。因此,我们在迁移中添加了checked约束,但没有在代码模型中添加。因此,在创建新的初始迁移时,选中的约束不是迁移的一部分

  • 作为一个实验,我尝试从所有旧迁移中删除模型快照,因为快照占代码的90%,这导致编译时间过长。我发现,EFCore只将快照用作进行新迁移的比较工具。删除快照后,旧迁移在新数据库上运行时将不再执行


  • 那么,有没有更好的方法来实现我的目标呢?

    好吧,既然问了这个问题,我已经尝试了很多

    目前看来,实现这一目标的最佳方式是选择1。选项2会更好,但在实现之前,它对于我的用例(支持在现有数据库上进行迁移的数据库,以及支持空数据库)来说是不可行的

    选项1也有一些我偶然发现的陷阱(也许更多的是我没有偶然发现的)。 我就是这样做的:

    创建新的初始迁移:

  • 确保已将所有现有迁移应用于数据库。我们将创建一个新的初始迁移,因此尚未应用的迁移将丢失
  • 删除旧的EFCore迁移文件和数据库快照文件
  • 从数据库的当前状态创建新的初始迁移。(例如,通过
    dotnet ef迁移添加初始后清理
  • 此新迁移仅与新数据库兼容,因为它将创建所有表(如果任何表、约束等已经存在,则将失败)。因此,现在我们要使此迁移与现有数据库兼容:

  • 通过
    dotnet ef migrations script-o script.SQL
    为新的初始迁移创建SQL脚本
  • 删除第一个事务(直到第一个
    GO
    ),这将创建
    \uuu EFMigrationsHistory
    表:
  • 如果对象\u ID(N'[\u EFMigrationsHistory]'为空
    开始
    创建表[\uu EFMigrationsHistory](
    [MigrationId]nvarchar(150)不为空,
    [ProductVersion]nvarchar(32)不为空,
    约束[PK__EFMigrationHistory]主键([MigrationId])
    );
    结束;
    去
    
  • 删除最后一个事务,该事务将在
    \u EFMigrationsHistory
    表中插入新条目:
  • 插入[\uuu EFMigrationsHistory]([MigrationId]、[ProductVersion])
    数值(N'20190704144924_初始-后清理',N'2.2.4-维修-10062');
    去
    
  • 删除
    GO
    命令,因为我们将把创建脚本放在IF语句中:
    GO\r\n\r\n
    替换为空
  • 现在打开您的迁移文件(C#文件,而不是sql文件),并用以下内容替换
    up
    方法:
  • protected override void Up(MigrationBuilder MigrationBuilder)
    {
    migrationBuilder.Sql(@)
    声明@migrationscont INT=(从[dbo]中选择COUNT(*)。[uuu\EFMigrationsHistory])
    如果@migrationscont=0
    开始
    %将编辑的SQL脚本粘贴到此处%
    结束
    ");
    }
    
    完成了!现在一切都应该开始了


    请确保比较新数据库的数据库架构以及之前和之后的数据。如果您的EF代码模型不是新数据库的一部分,那么所有这些都不是新数据库的一部分。

    有点晚了,但我们在当前项目中遇到了相同的问题。400次以上的迁移和6百万行的代码。以下是我们如何解决此问题的:

    MigrationProject.csproj

    
    ...
    $(默认项目除外);迁移\***.Designer.cs
    

    这样,您就不需要将迁移重置为清除状态,也不需要删除.Designer文件。您始终可以通过任何必要的方式更改配置以发布和使用.Designer文件。

    要从头重置所有迁移和更新(假设磁盘上没有有用的数据),以下步骤可能有用


    (1) 请确保program.cs文件未针对使用Database.com命令创建/更新数据库进行优化,因为此命令会阻止迁移。
    (2) 删除文件夹迁移。
    (3) dotnet构建
    (4) dotnet ef数据库更新0-c yourContextFile
    (5) dotnet ef迁移添加init-c yourContextFile

    (6) dotnet ef数据库更新-c yourContextFile

    奇怪,根据,解决方案2可能已经工作了。刚刚测试了解决方案2是否在EFCore 2.0上工作。遇到了与我描述的相同的问题(fresh db在没有设计器文件的情况下不运行迁移)。我在解决方案2的EFCore repo上创建了一个问题:第一个解决方案对我有效,但是是的,您提到了一个很好的点,它可能会很危险。工作非常好,请确保从旧迁移中重新添加自定义脚本。例如,我必须添加代码来创建一个本来不存在的视图
      <PropertyGroup>
         ...
         <DefaultItemExcludes Condition="'$(Configuration)' == 'Debug' ">$(DefaultItemExcludes);Migrations\**\*.Designer.cs</DefaultItemExcludes>
      </PropertyGroup>