我们有一个包含约 200 个表的数据库架构。 为每次迁移创建的模型快照 (Migration.Designer.cs) 约为 20K 行。因此,进行大量迁移确实会减慢我们在 CI 上的构建速度(大约 30 次迁移,构建解决方案需要 6 分钟(有迁移)或 4 分钟(无迁移)。
那么,对于这个问题:删除旧迁移的模型快照是否安全(我们知道我们永远不会恢复)?模型快照除了恢复迁移之外还有其他用途吗?
模型快照除了恢复迁移之外还有其他用途吗?
是的。有一些需要它的边缘情况。在 SQL Server 上,这些情况是:
所以大多数时候删除可能是安全的,但请测试删除后您的迁移是否仍然有效。
.Designer.cs 文件包含一个分部类,具有 2 个属性:
[DbContext...
[Migration...
不要忘记将这些属性复制到包含迁移代码的类(同一分部类的 Up 和 Down 方法)。 EF 使用这些属性来确定程序集中有哪些迁移。
从项目中删除 .Designer.cs 文件后,dbContext.Database.GetPendingMigrations().Count() 返回 0。
我们通过添加这些属性解决了这个问题。
我当前的项目遇到了同样的问题。 .Designer 内超过 400 个迁移和 600 万行代码。这是我设法解决这个问题的方法:
迁移项目.csproj
<PropertyGroup>
...
<DefaultItemExcludes Condition="'$(Configuration)' == 'Debug' ">$(DefaultItemExcludes);Migrations\**\*.Designer.cs</DefaultItemExcludes>
</PropertyGroup>
这样您不需要重置迁移,也不需要删除.Designer 文件。
编辑:这是一种临时解决方法,有一天您需要重置您的 migraitons。
这是 Jaime Yule 方法的改进。
在开发中,我希望能够测试当前的迁移,并在合并其他分支时执行落在我的分支上的迁移。因此,我没有排除所有设计器文件,而是保留最新的文件,如下所示:
<PropertyGroup Condition="'$(Configuration)'=='DEBUG'">
<CurrentYear>$([System.DateTime]::Now.Year)</CurrentYear>
<CurrentMonth>$([System.DateTime]::Now.Month.ToString("00"))</CurrentMonth>
<DefaultItemExcludes>$(DefaultItemExcludes);Migrations\*.Designer.cs</DefaultItemExcludes>
</PropertyGroup>
<ItemGroup>
<Compile Include="Migrations\$(CurrentYear)$(CurrentMonth)*.Designer.cs" />
</ItemGroup>
当然,为了完全无懈可击,还必须包括前一个月。像这样:
<PropertyGroup Condition="'$(Configuration)'=='DEBUG'">
<CurrentMonth>$([System.DateTime]::Now.Month.ToString("00"))</CurrentMonth>
<YearOfCurrentMonth>$([System.DateTime]::Now.Year)</YearOfCurrentMonth>
<LastMonth>$([System.DateTime]::Now.AddMonths(-1).Month.ToString("00"))</LastMonth>
<YearOfLastMonth>$([System.DateTime]::Now.AddMonths(-1).Year)</YearOfLastMonth>
<DefaultItemExcludes>$(DefaultItemExcludes);Migrations\*.Designer.cs</DefaultItemExcludes>
</PropertyGroup>
<ItemGroup>
<Compile Include="Migrations\$(YearOfCurrentMonth)$(CurrentMonth)*.Designer.cs" />
<Compile Include="Migrations\$(YearOfLastMonth)$(LastMonth)*.Designer.cs" />
</ItemGroup>
最后但并非最不重要的一点是,我们决定省略
'$(Configuration)'=='DEBUG'
条件,因为我们仅在生产中滚动,而对于开发,我们使用 EnsureCreated。所以没有必要保留所有迁移的历史记录。
.Designer.cs 文件包含一个分部类,具有 2 个属性:
[DbContext...
[Migration...
不要忘记将这些属性复制到包含迁移代码的类(同一分部类的 Up 和 Down 方法)。 EF 使用这些属性来确定程序集中有哪些迁移。
从项目中删除 .Designer.cs 文件后,dbContext.Database.GetPendingMigrations().Count() 返回 0。
我们通过添加这些属性解决了这个问题。
根据 Jaime Yule、Dejan 和 bricelam 的回答,我创建了一个 MSBuild 任务来尝试自动解决此问题。您所要做的就是安装任务。
它会自动将这些属性从
*.Designer.cs
文件移动到主代码文件:
[DbContext...
[Migration...
它将
*.Designer.cs
文件设置为不编译:
<DefaultItemExcludes>$(DefaultItemExcludes);**\*.Designer.cs</DefaultItemExcludes>
然后,它会查找最新的
N
(可配置数量)*.Designer.cs 文件,并专门启用它们进行编译:
<Compile Include="xxx" />
安装:
dotnet add package MSBuild.EntityFrameworkCore.RemoveDesignerCompilation --prerelease
(在发布稳定版本之前,您必须使用
--prerelease
。我想先收集一些预发布反馈)