清除旧的Entity Framework Core迁移的推荐方法

时间:2019-06-28 08:51:37

标签: entity-framework .net-core entity-framework-core

在开发应用程序一段时间后,我们已经积累了很多EFCore数据库迁移。由于EFCore会在每次迁移中添加整个数据库模型的快照,因此此代码加起来很多。经过分析,我们约80%的编译时间都花在了迁移上(编译+ Roslyn分析器)。

现在该清理一些旧的迁移了!但是最好的方法是什么?似乎没有任何官方指导...

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

我尝试过的事情:

  1. 最核心的选择似乎是删除所有迁移和模型快照,然后创建一个新的初始迁移。尽管这很好,但似乎有些危险。使用这种方法,我们需要非常小心,使数据库架构的每个部分都成为代码模型的一部分。例如,我们遇到的一个极端情况是EFCore还不支持检查的约束。因此,我们在迁移中添加了检查约束,但未添加代码模型。因此,在创建新的初始迁移时,检查的约束不属于其中。

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

那么有什么更好的方法来完成我想要的吗?

3 个答案:

答案 0 :(得分:0)

好的,自从问了这个问题以来,我已经对此做了很多试验。

目前看来,完成此操作的最佳方法是选项1。选项2会好得多,但是在实施this EFCore feature之前,它对我的​​用例而言确实不可行(支持在现有数据库上进行迁移)它们,并支持空的数据库。

选项1也有我偶然发现的一些陷阱(甚至可能更多我没有偶然发现的陷阱)。 所以这就是我的做法:

创建新的初始迁移:

  1. 确保所有现有迁移都已应用到数据库。我们将创建一个新的初始迁移,因此尚未应用的迁移将丢失。
  2. 删除旧的EFCore迁移文件和数据库快照文件。
  3. 从数据库的当前状态创建新的初始迁移。 (例如,通过dotnet ef migrations add Initial-PostCleanup。)

此新迁移仅与新数据库兼容,因为它将创建所有表(如果任何表,约束等已经存在,将失败)。现在,我们要使此迁移与现有数据库兼容:

  1. 通过dotnet ef migrations script -o script.sql为新的初始迁移创建SQL脚本。
  2. 删除第一笔交易(直到第一笔GO),这将创建__EFMigrationsHistory表:
IF OBJECT_ID(N'[__EFMigrationsHistory]') IS NULL
BEGIN
    CREATE TABLE [__EFMigrationsHistory] (
        [MigrationId] nvarchar(150) NOT NULL,
        [ProductVersion] nvarchar(32) NOT NULL,
        CONSTRAINT [PK___EFMigrationsHistory] PRIMARY KEY ([MigrationId])
    );
END;

GO
  1. 删除最后一个事务,该事务将新条目插入__EFMigrationsHistory表中:
INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
VALUES (N'20190704144924_Initial-PostCleanup', N'2.2.4-servicing-10062');

GO
  1. 删除GO命令,因为我们会将创建脚本放入IF语句中:
    GO\r\n\r\n替换为空。
  2. 现在打开您的迁移文件(C#文件,而不是sql文件),并将Up方法替换为以下内容:
protected override void Up(MigrationBuilder migrationBuilder)
{
    migrationBuilder.Sql(@"
DECLARE @migrationsCount INT = (SELECT COUNT(*) FROM [dbo].[__EFMigrationsHistory])
IF @migrationsCount = 0
BEGIN
    % PASTE YOUR EDITED SQL SCRIPT HERE %
END
");
}

完成!一切都应该正常工作!

请确保比较数据库架构以及新数据库之前和之后的数据。如果您的EF代码模型不属于新数据库,则不属于所有内容。

答案 1 :(得分:0)

有点晚了,但是我们在当前项目中遇到了同样的问题。 .Designer中包含400多个migraitons和6m行代码。这是我们设法解决此问题的方法:

MigrationProject.csproj

insertlayer

这样,您无需将迁移重置为清晰状态,也无需删除.Designer文件。您随时可以通过任何必要的方式将配置更改为Release,然后使用.Designer文件。

答案 2 :(得分:0)

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


(1)确保未对program.cs文件进行优化以通过Database.EnsureCreate命令创建/更新数据库,因为此命令可防止迁移。
(2)删除文件夹迁移。
(3)建立dotnet
(4)dotnet ef数据库更新0 -c yourContextFile
(5)dotnet ef迁移添加init -c yourContextFile
(6)dotnet ef数据库更新-c yourContextFile