DaI*_*mTo 6 c# entity-framework-core .net-core
我正在尝试创建一个自定义迁移步骤来清理我们数据库中的一些默认值。基本上我们有一些无效的数据需要更新,而在其他情况下它根本不存在。该系统安装在多台服务器上,其中很多数据是一次性手动添加的,因此很难知道哪个服务器有哪些数据。
我想要做的是创建一个迁移步骤来清理它。如果表中不存在此值,我需要插入它。但是,如果它确实存在,那么我要么更新它,要么删除它然后插入它。我很难弄清楚如何做到这一点。
Add-Migration DataCleanup
Run Code Online (Sandbox Code Playgroud)
创建迁移步骤
public partial class DataCleanup : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.InsertData(
table: "Blogs",
columns: new[] { "BlogId", "Url" },
values: new object[] { 4, "http://sample4.com" });}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DeleteData(
table: "Blogs",
keyColumn: "BlogId",
keyValue: 4);
}
}
Run Code Online (Sandbox Code Playgroud)
如果该行以前不存在,这将起作用,但如果该行确实存在,那么我将需要更新以确保该值是正确的值。我不担心主键,因为这是一个参考表,它们“应该”相同。
我能想到的唯一其他选择是在这些表上运行截断,然后在之后运行插入。
migrationBuilder.Sql("TRUNCATE TABLE [Blogs]", true);
Run Code Online (Sandbox Code Playgroud)
注意下
我倾向于完全不能做向下。在我运行它之前,将无法知道这台服务器处于什么状态。
首先,我无法在表上进行截断,因为设置了外键,这意味着那是行不通的。
我最终做了一堆 sql 插入,检查第一行是否存在,如果不存在,则我们插入它。
migrationBuilder.Sql("INSERT INTO IdentityResources (Description, DisplayName, Emphasize, Enabled, Name, Required, ShowInDiscoveryDocument) " +
"SELECT 'Your email address', 'User email', 1, 1, 'email', 0, 1 " +
"WHERE NOT EXISTS(SELECT * " +
"FROM IdentityResources " +
"WHERE name = 'email'); ", true);
Run Code Online (Sandbox Code Playgroud)
当我需要从第一个插入中添加密钥时,事情变得有点复杂。
migrationBuilder.Sql("INSERT INTO IdentityClaims (IdentityResourceId, Type) " +
"SELECT id, 'email' " +
"FROM IdentityResources " +
"WHERE Name = 'email' " +
"AND NOT EXISTS(SELECT * " +
"FROM [IdentityClaims] " +
"WHERE type = 'email')");
Run Code Online (Sandbox Code Playgroud)
这一切最终都解决了。系统的新安装会构建正确的数据库,并且每个人都会得到更新以确保他们至少拥有所需的数据。
不幸的是,删除不需要的数据将不得不等待另一天。
| 归档时间: |
|
| 查看次数: |
3142 次 |
| 最近记录: |