1

我知道很多人在EF 4.1上詢問一對一關係,但我似乎無法找到此問題的答案。EF 4.1代碼優先 - 使用非標準列名稱映射一對一關係

我有這些POCO類:

public class Contact 
{ 
    public decimal nCont_id { get; set; } 

    public virtual WebsiteMembership WebsiteMembership { get; set; } 
    //a bunch of other properties 
} 

public class WebsiteMembership 
{ 
    public int WebsiteMembershipId { get; set; } 

    public virtual Contact Contact { get; set; } 
} 

網站會員的主鍵(WebsiteMembershipId)也是一個外鍵引用聯繫人的nCont_id。

我試圖設置此使用流利的API:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    //This is being done because of the unconventional column names I have to live with 
    modelBuilder.Conventions.Remove<NavigationPropertyNameForeignKeyDiscoveryConvention>(); 

    //bunch of other stuff 
    modelBuilder.Entity<Contact>().ToTable("contacts"); 
    modelBuilder.Entity<Contact>().HasKey(b => b.nCont_id); 
    modelBuilder.Entity<Contact>().HasOptional(b => b.WebsiteMembership).WithRequired(b => b.Contact).Map(b => b.MapKey("WebsiteMembershipId")); 

    modelBuilder.Entity<WebsiteMembership>().ToTable("WebsiteMembership"); 
    modelBuilder.Entity<WebsiteMembership>().HasKey(b => b.WebsiteMembershipId); 

} 

,但我得到當我嘗試做一個例外:

var websiteMembership = context.WebsiteMemberships.Where(c => c.WebsiteMembershipId == 1645942).FirstOrDefault(); 

例外:

模式指定無效。錯誤:(263,6):錯誤0019:類型中的每個 屬性名稱必須是唯一的。物業名稱 'WebsiteMembershipId'已被定義。

這是否意味着我無法在EF CodeFirst上將外鍵設置爲相同的主鍵?或者我在這裏做錯了什麼?如果主鍵與外鍵不是同一列,它會起作用嗎?

建議非常感謝!

回答

3

我認爲當你定義這個映射...

modelBuilder.Entity<Contact>() 
    .HasOptional(b => b.WebsiteMembership) 
    .WithRequired(b => b.Contact) 
    .Map(b => b.MapKey("WebsiteMembershipId")); 

...你隱含定義什麼是主,什麼是從屬的關係。顯然Contact是主要原因,因爲WebsiteMembership屬性集對於Contact是可選的,所以它可以在沒有WebsiteMembership的情況下存儲。另一方WebsiteMembership實體需要參考Contact,這意味着它取決於Contact

委託人(Contact)是具有主鍵的實體,依賴於具有外鍵的實體(WebsiteMembership)。因此,當您使用MapKey來設置外鍵列的名稱WebsiteMembershipId時,您將爲表WebsiteMembership定義一個列,而不是Contact。但WebsiteMembership已經有一個名爲WebsiteMembershipId的屬性。 (我相信這是EF抱怨說屬性名'WebsiteMembershipId'已被定義爲。)在一對多關係中,外鍵是ContactId作爲單獨的屬性/列,您必須使用HasForeignKey而不是MapKey。但是在一對一的關係中,顯然外鍵是同時的主鍵,所以你根本不需要定義外鍵。

短長話短說:只是刪除MapKey

modelBuilder.Entity<Contact>() 
    .HasOptional(b => b.WebsiteMembership) 
    .WithRequired(b => b.Contact); 

(但現在我很好奇,如果你可以定義一個intdecimal屬性之間的關係,或者如果你得到一個錯誤)

+0

優秀的解釋!非常感謝你一切正常。我以前試過上面這段代碼,但是因爲我的字段是'int'而不是'decimal',EF正在尋找Contact_nCont_id字段。然後我使用了你的代碼片段並製作了「decimal」屬性,一切都很好用。 –