我正在尝试创建一个自定义迁移步骤,以清理数据库中的一些默认值。基本上,我们有一些无效的数据,需要更新,而在其他情况下则根本不存在。该系统安装在多台服务器上,并且很多数据是手动添加的,因此很难知道哪台服务器具有哪些数据。
我要做的是创建一个迁移步骤来清理所有内容。如果表中不存在此值,则需要将其插入。但是,如果确实存在,那么我要么更新它,要么删除它,然后将其插入。我很难弄清楚该怎么做。
Add-Migration DataCleanup
创建迁移步骤
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);
}
}
如果该行以前不存在,这将起作用,但是如果该行确实存在,那么我将需要更新以确保该值是正确的值。我不必担心主键,因为这是一个“应该”相同的参考表。
我唯一想到的另一种选择是对这些表运行截断,然后在其后运行插入。
migrationBuilder.Sql("TRUNCATE TABLE [Blogs]", true);
注意事项
我倾向于完全不做任何事情。在我运行此服务器之前,将无法知道该服务器处于什么状态。
答案 0 :(得分:0)
首先,我无法在表上进行截断,但设置了外键,这意味着那将是行不通的。
我最终做了一堆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);
当我需要从第一个插入处添加密钥时,事情变得有些复杂了。
migrationBuilder.Sql("INSERT INTO IdentityClaims (IdentityResourceId, Type) " +
"SELECT id, 'email' " +
"FROM IdentityResources " +
"WHERE Name = 'email' " +
"AND NOT EXISTS(SELECT * " +
"FROM [IdentityClaims] " +
"WHERE type = 'email')");
这一切最终都解决了。新安装的系统将构建适当的数据库,并且每个人都将得到更新以确保他们至少拥有所需的数据。
不幸的是,删除不需要的数据将不得不等待另一天。