如何在此 Entity Framework 6.x 迁移期间更新基础数据?
How can I update the underlying data during this Entity Framework 6.x migration?
概述
我正在尝试从原始设计更新现有应用程序(为清楚起见进行了简化):
// Current design
class Audit {
int Number { get; set; }
Person Supervisor { get; set; }
}
class Person {
int ID { get; set; }
string Name { get; set; }
}
以下使用单独主管的设计class:
// Improved design
class Audit {
int Number { get; set; }
Supervisor Supervisor { get; set; }
}
class Supervisor {
int ID { get; set; }
Person Person { get; set; }
// ...other supervisor properties
}
class Person {
int ID { get; set; }
string Name { get; set; }
}
目标是将 Supervisor
相关属性与 Person
class 和相应的数据库 table.
分开
问题
如何更新基础数据以便
- 为审计 table、
中每个现有的唯一 Supervisor_ID 创建一个新的主管行
- 新主管的Person_ID指向正确的人,
- 审计的 Supervisor_ID 更新为新主管的 ID。
这是否可以在迁移期间在 EF 迁移的 Up()
函数(或可能在其他地方)中完成,或者我是否需要使用手工制作的 SQL 脚本单独解决这个问题?
当我意识到它不必是专门的 (1) DbContext 或 (2) 独立的 SQL 脚本时,我想出了这个运行 SQL 的解决方案迁移:
public override void Up()
{
CreateTable(
"dbo.Supervisor",
c => new
{
ID = c.Int(nullable: false, identity: true),
Active = c.Boolean(nullable: false),
Person_ID = c.Int(nullable: false),
})
.PrimaryKey(t => t.ID)
.ForeignKey("dbo.Person", t => t.Person_ID, cascadeDelete: true)
.Index(t => t.Person_ID);
// for each unique Supervisor_ID in audits create a new supervisor with that Person_ID
Sql("INSERT INTO Supervisor(Person_ID, Active) SELECT DISTINCT Supervisor_ID, 1 FROM Audit;");
DropForeignKey("dbo.Audit", "Supervisor_ID", "dbo.Person");
// for each audit update Supervisor_ID to the ID of the supervisor with that Person_ID
Sql("UPDATE Audit SET Audit.Supervisor_ID = Supervisor.ID FROM Audit JOIN Supervisor ON Audit.Supervisor_ID = Supervisor.Person_ID;");
AddForeignKey("dbo.Audit", "Supervisor_ID", "dbo.Supervisor");
}
我仍然很想知道除了这种方法之外是否还有其他方法。
更新 2021-04-26
看起来迁移没有检测到 FK 的变化,所以这个答案是不完整的。更新了答案以包括外键的手动更改。
概述
我正在尝试从原始设计更新现有应用程序(为清楚起见进行了简化):
// Current design
class Audit {
int Number { get; set; }
Person Supervisor { get; set; }
}
class Person {
int ID { get; set; }
string Name { get; set; }
}
以下使用单独主管的设计class:
// Improved design
class Audit {
int Number { get; set; }
Supervisor Supervisor { get; set; }
}
class Supervisor {
int ID { get; set; }
Person Person { get; set; }
// ...other supervisor properties
}
class Person {
int ID { get; set; }
string Name { get; set; }
}
目标是将 Supervisor
相关属性与 Person
class 和相应的数据库 table.
问题
如何更新基础数据以便
- 为审计 table、 中每个现有的唯一 Supervisor_ID 创建一个新的主管行
- 新主管的Person_ID指向正确的人,
- 审计的 Supervisor_ID 更新为新主管的 ID。
这是否可以在迁移期间在 EF 迁移的 Up()
函数(或可能在其他地方)中完成,或者我是否需要使用手工制作的 SQL 脚本单独解决这个问题?
当我意识到它不必是专门的 (1) DbContext 或 (2) 独立的 SQL 脚本时,我想出了这个运行 SQL 的解决方案迁移:
public override void Up()
{
CreateTable(
"dbo.Supervisor",
c => new
{
ID = c.Int(nullable: false, identity: true),
Active = c.Boolean(nullable: false),
Person_ID = c.Int(nullable: false),
})
.PrimaryKey(t => t.ID)
.ForeignKey("dbo.Person", t => t.Person_ID, cascadeDelete: true)
.Index(t => t.Person_ID);
// for each unique Supervisor_ID in audits create a new supervisor with that Person_ID
Sql("INSERT INTO Supervisor(Person_ID, Active) SELECT DISTINCT Supervisor_ID, 1 FROM Audit;");
DropForeignKey("dbo.Audit", "Supervisor_ID", "dbo.Person");
// for each audit update Supervisor_ID to the ID of the supervisor with that Person_ID
Sql("UPDATE Audit SET Audit.Supervisor_ID = Supervisor.ID FROM Audit JOIN Supervisor ON Audit.Supervisor_ID = Supervisor.Person_ID;");
AddForeignKey("dbo.Audit", "Supervisor_ID", "dbo.Supervisor");
}
我仍然很想知道除了这种方法之外是否还有其他方法。
更新 2021-04-26
看起来迁移没有检测到 FK 的变化,所以这个答案是不完整的。更新了答案以包括外键的手动更改。