2011-06-08 47 views
9

我想使用EF Code First創建兩個實體之間的雙向One-One關係。我在下面的代碼中遇到了問題。你覺得我應該怎麼做?在Entity Framework中創建雙向One-One關係4.1代碼優先

public class User 
{ 
    public string ID { get; set; } 
    public string LastName { get; set; } 
    public string Password { get; set; } 
    public string FirstName { get; set; } 

    public int ProfileID { get; set; } 
    public Profile Profile { get; set; } 

} 
public class Profile 
{ 
    public int UserID { get; set; } 
    public User User { get; set; } 
    public int ProfileID { get; set; } 
    public string ProfileName { get; set; } 

    public DateTime CreateDate { get; set; } 
    public DateTime LastUpdateDate { get; set; } 

} 

我想在這兩個實體中同時具有導航屬性和外鍵。

這給了我錯誤。在Fluent Mapping API中可以做些什麼來實現這個功能?

+0

你得到的錯誤是什麼? – Eranga 2011-06-08 08:50:43

回答

17

使用此:

public class User 
{ 
    public string ID { get; set; } 
    public string LastName { get; set; } 
    public string Password { get; set; } 
    public string FirstName { get; set; } 
    public Profile Profile { get; set; } 
} 

public class Profile 
{ 
    [Key, ForeignKey("User")] 
    public int ProfileID { get; set; } 
    public string ProfileName { get; set; } 
    public DateTime CreateDate { get; set; } 
    public DateTime LastUpdateDate { get; set; } 
    public User User { get; set; } 
} 

這是建立在EF一個一對一的關係,唯一有效的方式 - 依靠實體的PK也必須FK到主要實體。在EF中沒有像雙向一對一的關係,因爲它不能在EF中工作。

人們如何克服這種情況的方式是兩個一對多的關係,其中principal沒有依賴實體的導航集合+在數據庫中手動定義唯一鍵。需要手動映射:

public class User 
{ 
    public string ID { get; set; } 
    public string LastName { get; set; } 
    public string Password { get; set; } 
    public string FirstName { get; set; } 
    // one side MUST be nullable otherwise you have bidirectional constraint where each 
    // entity demands other side to be inserted first = not possible 
    public int? ProfileId { get; set; } 
    public Profile Profile { get; set; } 
} 

public class Profile 
{ 
    public int ProfileID { get; set; } 
    public string ProfileName { get; set; } 
    public DateTime CreateDate { get; set; } 
    public DateTime LastUpdateDate { get; set; } 
    public int UserId { get; set; } 
    public User User { get; set; } 
} 

而在映射將定義:

modelBuilder.Entity<User> 
      .HasOptional(u => u.Profile) 
      .WithMany() 
      .HasForeignKey(u => u.ProfileId); 
modelBuilder.Entity<Profile> 
      .HasRequired(u => u.User) 
      .WithMany() 
      .HasForeignKey(u => u.UserId); 

現在您必須在數據庫中定義唯一的鑰匙 - 如果你正在使用的代碼先使用custom database initialize河請注意,仍然雙向一對一是錯誤的概念,因爲雙方都要求唯一的FK,其中NULL仍然包含在唯一值中,因此一旦在Profile之前插入User,則不得有任何其他User而沒有Profile。這可能會導致可序列化的事務。

+0

拉迪斯拉夫,現在它變得非常有意義......我理解這些關係是如何製作的...儘管我同意它應該以更好的方式支持以手動創建獨特的關鍵... – InvisibleDev 2011-06-10 17:00:53

+0

爲什麼WithMany如果這是一次性的,一對一的關係? – angel 2016-08-25 16:55:55

+0

@angel:這是一個克服EF限制的解決方法 - 答案的第二部分是通過告訴EF有兩個一對多關係而不是直接映射一對一來欺騙EF。通過在外鍵列上放置唯一的鍵約束來確保數據庫級的一對一。 – 2016-08-29 22:42:47

相關問題