Entity Framework Core:如果我们永远不会恢复迁移,删除 Migration.Designer.cs 是否安全?

问题描述 投票:0回答:5

我们有一个包含约 200 个表的数据库架构。 为每次迁移创建的模型快照 (Migration.Designer.cs) 约为 20K 行。因此,进行大量迁移确实会减慢我们在 CI 上的构建速度(大约 30 次迁移,构建解决方案需要 6 分钟(有迁移)或 4 分钟(无迁移)。

那么,对于这个问题:删除旧迁移的模型快照是否安全(我们知道我们永远不会恢复)?模型快照除了恢复迁移之外还有其他用途吗?

c# entity-framework-core entity-framework-migrations
5个回答
21
投票

模型快照除了恢复迁移之外还有其他用途吗?

是的。有一些需要它的边缘情况。在 SQL Server 上,这些情况是:

  • AlterColumn 当列缩小或计算表达式更改并且需要重建索引时
  • 当索引唯一且引用可为空列时,在内存优化表上创建索引

所以大多数时候删除可能是安全的,但请测试删除后您的迁移是否仍然有效。


.Designer.cs 文件包含一个分部类,具有 2 个属性:

[DbContext...
[Migration...

不要忘记将这些属性复制到包含迁移代码的类(同一分部类的 Up 和 Down 方法)。 EF 使用这些属性来确定程序集中有哪些迁移。

从项目中删除 .Designer.cs 文件后,dbContext.Database.GetPendingMigrations().Count() 返回 0。

我们通过添加这些属性解决了这个问题。


11
投票

我当前的项目遇到了同样的问题。 .Designer 内超过 400 个迁移和 600 万行代码。这是我设法解决这个问题的方法:

迁移项目.csproj

  <PropertyGroup>
     ...
     <DefaultItemExcludes Condition="'$(Configuration)' == 'Debug' ">$(DefaultItemExcludes);Migrations\**\*.Designer.cs</DefaultItemExcludes>
  </PropertyGroup>

这样您不需要重置迁移,也不需要删除.Designer 文件。

编辑:这是一种临时解决方法,有一天您需要重置您的 migraitons。


5
投票

这是 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。所以没有必要保留所有迁移的历史记录。


4
投票

.Designer.cs 文件包含一个分部类,具有 2 个属性:

[DbContext...
[Migration...

不要忘记将这些属性复制到包含迁移代码的类(同一分部类的 Up 和 Down 方法)。 EF 使用这些属性来确定程序集中有哪些迁移。

从项目中删除 .Designer.cs 文件后,dbContext.Database.GetPendingMigrations().Count() 返回 0。

我们通过添加这些属性解决了这个问题。


1
投票

根据 Jaime YuleDejanbricelam 的回答,我创建了一个 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
。我想先收集一些预发布反馈)

NuGet

GitHub

© www.soinside.com 2019 - 2024. All rights reserved.