[英]One-to-one Mapping issue with NHibernate/Fluent: Foreign Key not updateing
[英]One-To-One Mapping issue
我的SQL理解是相當基礎的,我來自NHibernate的世界,所以我對這個問題感到很困惑......
我有兩節課:
public class UserProfile
{
public UserProfile() { }
[Key]
public int UserId { get; set; }
public string UserName { get; set; }
public SerialNumber Serial { get; set; }
// Other properties
}
和
public class SerialNumber
{
public SerialNumber()
{
// My code that creates a unique Code
}
[Key]
public string Code { get; set; }
public UserProfile User { get; set; }
// Other Properties
}
我有這個
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// Other modelBuilder stuff
modelBuilder.Entity<UserProfile>()
.HasOptional(s => s.Serial)
.WithRequired(u => u.User);
}
運行Add-Migration
我得到了這個:
public override void Up()
{
DropForeignKey("dbo.UserProfile", "Serial_Code", "dbo.SerialNumbers");
DropIndex("dbo.UserProfile", new[] { "Serial_Code" });
RenameColumn(table: "dbo.SerialNumbers", name: "Serial_Code", newName: "User_UserId");
AddForeignKey("dbo.SerialNumbers", "User_UserId", "dbo.UserProfile", "UserId");
CreateIndex("dbo.SerialNumbers", "User_UserId");
}
public override void Down()
{
// Inverse of above
}
運行Update-Database
我收到一個錯誤: "Either the parameter @objname is ambiguous or the claimed @objtype (COLUMN) is wrong."
我可以通過Add-Migration
生成的代碼告訴我出錯了,因為我的db表甚至沒有名為"Serial_Code"
我需要Code
作為我的Key
因為EntityFramework沒有選項強制列為Unique
除非使其成為鍵。
如何將Serial
作為UserProfile
的可選屬性,並將SerialNumber
User
添加到UserProfile
時自動設置?
默認情況下,在一對一關系中,Entity Framework要求依賴項上的外鍵也是主鍵。 這可能是因為實體框架僅對主鍵設置了唯一約束(或者說,由於它是主鍵,因此存在唯一約束)。 在數據庫的級別上,一對一不映射到關系的兩側,即在兩個表上都沒有創建外鍵。 當您考慮參照完整性如何工作時,這是有道理的:如果關系的一方被刪除,則會導致另一方的數據庫分離,導致一種無限循環。
因此,外鍵被添加到依賴項,在這種情況下,就像你在這里一樣,這就是具有所需導航屬性的結尾:你的SerialNumber
模型。 這意味着要真正創建一對一而不是一對多, SerialNumber
上的密鑰需要是User_UserId
(自動生成的外鍵列,因為您沒有手動指定外鍵屬性) )。 要以這種方式進行設置,您的模型將如下所示:
public class UserProfile
{
[Key]
public int UserId { get; set; }
public SerialNumber Serial { get; set; }
...
}
public class SerialNumber
{
[Key]
[ForeignKey("User")]
public int UserId { get; set; }
public UserProfile User { get; set; }
...
}
或者使用Fluent API:
modelBuilder.Entity<SerialNumber>()
.HasRequired(m => m.User)
.WithOptional(m => m.Serial);
(您需要省略[Key]
數據注釋,以便EF可以創建外鍵,它們是表的主鍵。)
但是,這使您在Code
屬性上沒有唯一約束。 您當然可以在表上手動設置此約束,或者如果您不使用自動遷移,則可以更改遷移以創建約束:
CreateIndex("dbo.SerialNumbers", "Code", unique: true);
這里的問題是實體框架不會為您處理唯一的驗證。 因此,您需要在代碼中手動維護完整性(即,嘗試使用您要保存的Code
查找SerialNumber
,並且只有在您從查詢中得不到任何內容時才保存它)。
我知道,這是一種痛苦,但就目前而言,這就是你所能做的一切。 希望EF能夠最終解決未來版本中的獨特性問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.