我的代码优先数据模型以标准ApplicationUser
实体开始,其中包括邮政地址和结算属性。现在我通过添加父Account
实体来扩展我的模型:
为了更新数据库模式以合并新的父表,我将每个现有的ApplicationUser分配给新创建的Account。所以,我需要为每个现有的ApplicationUser做两件事:
请注意,我的代码托管在Azure上,数据位于Azure SQL Server中。
scaffolded Migration代码看起来像这样(大大简化)
// Create the new Accounts table
CreateTable(
"dbo.Accounts",
c => new
{
Id = c.Int(nullable: false, identity: true),
BillingInfo = c.String(),
PostalAddress = c.String(),
})
.PrimaryKey(t => t.Id);
// Add the new FK column
AddColumn("dbo.AspNetUsers", "AccountId", c => c.Int(nullable: false));
CreateIndex("dbo.AspNetUsers", "AccountId");
// Before we add the AspNetUsers.AccountId foreign key, we need to populate
// the Accounts table (one Account for each User)
Sql("some SQL command(s)")
// Make the column a foreign key
AddForeignKey("dbo.AspNetUsers", "AccountId", "dbo.Accounts", "Id", cascadeDelete: true);
// Deleted fields
DropColumn("dbo.AspNetUsers", "BillingInfo");
DropColumn("dbo.AspNetUsers", "PostalAddress");
据我所知,创建或修改数据的唯一选择是使用Sql()
方法(或SqlFile()
或SqlResource()
),如上面的代码所示。
如果我只限于使用SQL,那么什么样的SQL命令才能完成任务?我可以在一个带有某种JOIN的大型命令(对于尚不存在的记录)中执行此操作,还是需要使用SQL循环(as shown in this article)?
答案 0 :(得分:1)
核心理念非常简单:
您的架构和数据迁移应位于不同的迁移类
对于迁移,您需要在要插入的一侧引入临时伪FK列,并使用此列迁移数据。高层次的想法看起来大致如下:
ALTER TABLE [dbo].[Accounts] ADD [_Temp_AspNetUserId] int; GO /*insert data into accounts with reference from AspNetUsers*/ INSERT INTO [dbo].[Accounts] (BillingInfo, PostalAddress, _Temp_AspNetUserId) SELECT user.BillingInfo, user.PostalAddress, user.Id FROM [dbo].[AspNetUsers] user /*update original foreign key relationship for [AspNetUsers] table*/ UPDATE [dbo].[AspNetUsers] SET AccountId = [dbo].[AspNetUsers].Id FROM [dbo].[Accounts] WHERE [dbo].[Accounts]._Temp_AspNetUserId = [dbo].[AspNetUsers].Id /*drop temporary column*/ ALTER TABLE [dbo].[Accounts] DROP COLUMN [_Temp_AspNetUserId]; GO
很抱歉格式化,出于某些原因,如果我不添加评论标记,它看起来有点搞砸了。