在开发应用程序一段时间后,我们已经积累了很多EFCore数据库迁移。由于EFCore会在每次迁移中添加整个数据库模型的快照,因此此代码加起来很多。经过分析,我们约80%的编译时间都花在了迁移上(编译+ Roslyn分析器)。
现在该清理一些旧的迁移了!但是最好的方法是什么?似乎没有任何官方指导...
我们不需要任何回滚(我们只需前滚),因此使事情变得更简单。我们确实需要支持从头开始创建数据库,并从最近的几次迁移中更新数据库。
我尝试过的事情:
最核心的选择似乎是删除所有迁移和模型快照,然后创建一个新的初始迁移。尽管这很好,但似乎有些危险。使用这种方法,我们需要非常小心,使数据库架构的每个部分都成为代码模型的一部分。例如,我们遇到的一个极端情况是EFCore还不支持检查的约束。因此,我们在迁移中添加了检查约束,但未添加代码模型。因此,在创建新的初始迁移时,检查的约束不属于其中。
作为一个实验,我尝试从所有旧的迁移中删除模型快照,因为快照占代码的90%,这会导致较长的编译时间。我认为EFCore仅将快照用作比较工具来进行新迁移。删除快照后,旧迁移在新数据库上运行时不再执行。
那么有什么更好的方法来完成我想要的吗?
答案 0 :(得分:0)
好的,自从问了这个问题以来,我已经对此做了很多试验。
目前看来,完成此操作的最佳方法是选项1。选项2会好得多,但是在实施this EFCore feature之前,它对我的用例而言确实不可行(支持在现有数据库上进行迁移)它们,并支持空的数据库。
选项1也有我偶然发现的一些陷阱(甚至可能更多我没有偶然发现的陷阱)。 所以这就是我的做法:
创建新的初始迁移:
dotnet ef migrations add Initial-PostCleanup
。)此新迁移仅与新数据库兼容,因为它将创建所有表(如果任何表,约束等已经存在,将失败)。现在,我们要使此迁移与现有数据库兼容:
dotnet ef migrations script -o script.sql
为新的初始迁移创建SQL脚本。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
__EFMigrationsHistory
表中:INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
VALUES (N'20190704144924_Initial-PostCleanup', N'2.2.4-servicing-10062');
GO
GO
命令,因为我们会将创建脚本放入IF语句中:GO\r\n\r\n
替换为空。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