Entity Framework 核心:如果我们永远不会还原迁移,删除 Migration.Designer.cs 是否安全?
Entity Framework Core: Is it safe to delete Migration.Designer.cs if we will never Revert a migration?
我们有一个包含约 200 个表的数据库模式。
为每次迁移创建的模型快照 (Migration.Designer.cs) 约为 20K 行。因此,进行大量迁移确实会减慢我们在 CI 上的构建速度(约 30 次迁移构建解决方案需要 6 分钟的迁移时间或 4 分钟的迁移时间)。
所以,对于这个问题:删除旧迁移的模型快照是否安全(我们知道我们永远不会恢复)?除了 Revert-Migration 之外,模型快照是否用于其他用途?
Are model snapshots used for anything else except Revert-Migration?
是的。有一些边缘情况需要它。在 SQL 服务器上,这些情况是:
- AlterColumn 当列变窄或计算表达式改变需要重建索引时
- 在内存优化 table 上创建索引,当索引是唯一的并且引用可为 null 的列时
所以大多数时候删除可能是安全的,但请测试您的迁移在删除后是否仍然有效。
.Designer.cs 文件包含部分 class,具有 2 个属性:
[DbContext...
[Migration...
不要忘记将这些属性复制到包含您的迁移代码的 class(同一部分 class 的 Up 和 Down 方法)。
EF 使用这些属性来确定程序集中有哪些迁移。
从我们的项目中删除 .Designer.cs 文件后,dbContext.Database.GetPendingMigrations().Count() 返回 0。
我们通过添加这些属性解决了这个问题。
我当前的项目遇到了同样的问题。 .Designer 中超过 400 migraitons 和 6m 行代码。以下是我设法解决此问题的方法:
MigrationProject.csproj
<PropertyGroup>
...
<DefaultItemExcludes Condition="'$(Configuration)' == 'Debug' ">$(DefaultItemExcludes);Migrations\**\*.Designer.cs</DefaultItemExcludes>
</PropertyGroup>
这样您就不需要重置迁移,也不需要删除 .Designer 文件。
编辑:这是一种临时解决方法,您需要有一天重新设置偏头痛。
这是对 Jaime Yule 方法的改进。
在开发中,我希望能够测试我当前的迁移并在合并其他分支时执行落在我的分支上的迁移。因此,我没有排除所有设计器文件,而是保留了最新的文件:
<PropertyGroup Condition="'$(Configuration)'=='DEBUG'">
<CurrentYear>$([System.DateTime]::Now.Year)</CurrentYear>
<CurrentMonth>$([System.DateTime]::Now.Month)</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)</CurrentMonth>
<YearOfCurrentMonth>$([System.DateTime]::Now.Year)</YearOfCurrentMonth>
<LastMonth>$([System.DateTime]::Now.AddMonths(-1).Month)</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 文件包含部分 class,具有 2 个属性:
[DbContext...
[Migration...
不要忘记将这些属性复制到包含您的迁移代码的 class(同一部分 class 的 Up 和 Down 方法)。
EF 使用这些属性来确定程序集中有哪些迁移。
从我们的项目中删除 .Designer.cs 文件后,dbContext.Database.GetPendingMigrations().Count() 返回 0。
我们通过添加这些属性解决了这个问题。
我们有一个包含约 200 个表的数据库模式。 为每次迁移创建的模型快照 (Migration.Designer.cs) 约为 20K 行。因此,进行大量迁移确实会减慢我们在 CI 上的构建速度(约 30 次迁移构建解决方案需要 6 分钟的迁移时间或 4 分钟的迁移时间)。
所以,对于这个问题:删除旧迁移的模型快照是否安全(我们知道我们永远不会恢复)?除了 Revert-Migration 之外,模型快照是否用于其他用途?
Are model snapshots used for anything else except Revert-Migration?
是的。有一些边缘情况需要它。在 SQL 服务器上,这些情况是:
- AlterColumn 当列变窄或计算表达式改变需要重建索引时
- 在内存优化 table 上创建索引,当索引是唯一的并且引用可为 null 的列时
所以大多数时候删除可能是安全的,但请测试您的迁移在删除后是否仍然有效。
.Designer.cs 文件包含部分 class,具有 2 个属性:
[DbContext...
[Migration...
不要忘记将这些属性复制到包含您的迁移代码的 class(同一部分 class 的 Up 和 Down 方法)。 EF 使用这些属性来确定程序集中有哪些迁移。
从我们的项目中删除 .Designer.cs 文件后,dbContext.Database.GetPendingMigrations().Count() 返回 0。
我们通过添加这些属性解决了这个问题。
我当前的项目遇到了同样的问题。 .Designer 中超过 400 migraitons 和 6m 行代码。以下是我设法解决此问题的方法:
MigrationProject.csproj
<PropertyGroup>
...
<DefaultItemExcludes Condition="'$(Configuration)' == 'Debug' ">$(DefaultItemExcludes);Migrations\**\*.Designer.cs</DefaultItemExcludes>
</PropertyGroup>
这样您就不需要重置迁移,也不需要删除 .Designer 文件。
编辑:这是一种临时解决方法,您需要有一天重新设置偏头痛。
这是对 Jaime Yule 方法的改进。
在开发中,我希望能够测试我当前的迁移并在合并其他分支时执行落在我的分支上的迁移。因此,我没有排除所有设计器文件,而是保留了最新的文件:
<PropertyGroup Condition="'$(Configuration)'=='DEBUG'">
<CurrentYear>$([System.DateTime]::Now.Year)</CurrentYear>
<CurrentMonth>$([System.DateTime]::Now.Month)</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)</CurrentMonth>
<YearOfCurrentMonth>$([System.DateTime]::Now.Year)</YearOfCurrentMonth>
<LastMonth>$([System.DateTime]::Now.AddMonths(-1).Month)</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 文件包含部分 class,具有 2 个属性:
[DbContext...
[Migration...
不要忘记将这些属性复制到包含您的迁移代码的 class(同一部分 class 的 Up 和 Down 方法)。 EF 使用这些属性来确定程序集中有哪些迁移。
从我们的项目中删除 .Designer.cs 文件后,dbContext.Database.GetPendingMigrations().Count() 返回 0。
我们通过添加这些属性解决了这个问题。