2011-05-16 158 views
26

我想在EF Code First中映射現有數據庫中的可選1對1關係。EF代碼優先 - 1對1可選關係

簡單模式:

User 
Username 
ContactID 

Contact 
ID 
Name 

顯然的ContactID加入到Contact.ID。 ContactID字段爲空,所以關係是可選的 - 0或1,從不多。

那麼,如何在EF Code First中使用此現有模式指定此關係?

這裏是我試過到目前爲止:

public class User 
{ 
    [Key] 
    public string Username { get; set; } 
    public int? ContactID { get; set; } 

    [ForeignKey("ContactID")] 
    public virtual Contact Contact { get; set; } 
} 

public class Contact 
{ 
    [Key] 
    public int ID { get; set; } 
    public string Name { get; set; } 

    public virtual User User { get; set; } 
} 

modelBuilder.Entity<User>().HasOptional<Contact>(u=> u.Contact) 
    .WithOptionalDependent(c => c.User); 

我得到以下異常:

System.Data.Edm.EdmAssociationEnd: : Multiplicity is not valid in Role 
'User_Contact_Source' in relationship 'User_Contact'. Because the Dependent 
Role properties are not the key properties, the upper bound of the multiplicity 
of the Dependent Role must be *. 

回答

42

一個解決辦法是;

public class User 
{ 
    [Key] 
    public string Username { get; set; } 

    public virtual Contact Contact { get; set; } 
} 

public class Contact 
{ 
    [Key] 
    public int ID { get; set; } 
    public string Name { get; set; } 

    public virtual User User { get; set; } 
} 

     modelBuilder.Entity<User>() 
      .HasOptional<Contact>(u => u.Contact) 
      .WithOptionalDependent(c => c.User).Map(p => p.MapKey("ContactID")); 

您只在POCO中設置了導航對象,而使用流利API將您的密鑰映射到正確的列。

+0

這幫助我在嘗試配置0:1到0:1時解決以下問題 - 此關聯的主體端必須使用關係流利API或數據註釋進行顯式配置。 – 2015-03-02 12:24:04

+1

我建議您按照約定包含外鍵屬性(https://msdn.microsoft.com/zh-cn/data/jj679962)。如果每當你創建實體之間的關係時,通過這個關鍵屬性而不是實體屬性來完成。我已經找到了這種方式,在對象狀態管理器中獲得某些異常(如重複鍵)的可能性較小,並且在更新出錯時更有意義的異常。 – MIP1983 2015-03-02 16:07:57

+9

如何在'User'中使用'ContactId'字段?如果我使用上面的代碼並在User中定義了一個'ContactId'字段,它會給我一個錯誤,說它是一個重複的屬性。我怎麼能告訴實體框架,用'MapKey'定義的列和用戶定義的'ContactId'是相同的。 – 2015-05-19 08:12:55