我遇到EF代碼第一次遷移與查找表和外鍵相關的問題。比方說,我有這兩個班在我的代碼:EF代碼首先使用空查找表設置外鍵
public class Test
{
[Key]
public long Id { get; set; }
[Required]
public string Title { get; set; }
[Required, DisplayName("Test type")]
public TestType TestType { get; set; }
}
public class TestType
{
public int Id { get; set; }
public string Name { get; set; }
}
TestType
是一個典型的查找表和我通常填滿他們的在Seed()
方法:
context.TestTypes.AddOrUpdate(
it => it.Name,
new TestType() { Name = "Drug" },
new TestType() { Name = "Educational" },
new TestType() { Name = "Other" }
);
當我創建表的關係我得到以下遷移:
CreateTable(
"dbo.TestTypes",
c => new
{
Id = c.Int(nullable: false, identity: true),
Name = c.String(),
})
.PrimaryKey(t => t.Id);
AddColumn("dbo.Tests", "TestType_Id", c => c.Int(nullable: false));
CreateIndex("dbo.Tests", "TestType_Id");
AddForeignKey("dbo.Tests", "TestType_Id", "dbo.TestTypes", "Id", cascadeDelete: true);
現在,如果我執行過程中的遷移,我會得到一個錯誤,因爲外鍵不能尊重GI事實上,查找表仍然是空的,並且創建的列沒有默認值。
在發展我能夠通過簡單地創建兩個遷移來解決這個問題,第一個創建的查找表,第二個設置外鍵。如果我分別運行它們,則第一個之後的Seed方法將填充表格,並且可以調整列創建以從DB中提取值以在創建外鍵之前預填充列,有點像這樣:
AddColumn("dbo.Tests", "TestType_Id", c => c.Int(nullable: false));
Sql("UPDATE dbo.Tests SET TestType_Id = (SELECT TOP 1 Id FROM dbo.TestTypes)");
CreateIndex("dbo.Tests", "TestType_Id");
AddForeignKey("dbo.Tests", "TestType_Id", "dbo.TestTypes", "Id", cascadeDelete: true);
然後當我運行它時,一切正常。
現在,在生產我沒有相同的奢侈品,因爲所有的遷移都在Seed方法運行之前運行,我總是會遇到同樣的問題。
我知道我可以潛在對生產數據庫運行在階梯順序遷移,以及但這並不能真正解決問題......假設我的一個同事更新他的工作副本並運行遷移,所有將按順序運行,他肯定會遇到錯誤。
TestType不應該創建表嗎? – Neil