2

我正在開發一個實體框架代碼優先(v。4.4.0.0)C#庫與.Net Framework 4.0。將導航屬性映射爲實例var作爲外鍵

我不知道如何設置零對一的關係。我的型號如下:

A Talk只能由一個用戶(StarterUserId)創建。
A Talk只能有一個接收用戶(RecepientUserId)或只有一個組(RecipientGroupId)。
注意:這意味着如果RecipientGroupId不爲空,那麼RecepientUserId爲空;或者如果RecipientGroupId爲空,則RecepientUserId不爲空。

A user可以是零或n的收件人Talks,但group可以有零個或一個Talk

這是通話類:

[DataContract] 
public class Talk 
{ 
    [DataMember] 
    public int TalkId { get; set; } 

    [DataMember] 
    public int StarterUserId { get; set; } 

    [DataMember] 
    public int? RecipientUserId { get; set; } 

    [DataMember] 
    [ForeignKey("RecipientGroup")] 
    public int? RecipientGroupId { get; set; } 

    public DateTime DateUtcStarted { get; set; } 

    [DataMember] 
    public string DateStarted 
    { 
     get 
     { 
      return DateUtcStarted.ToString("dd/MM/yyyy HH:mm"); 
     } 
     set 
     { 
      DateUtcStarted = DateTime.Parse(value); 
     } 
    } 

    public User StarterUser { get; set; } 
    public User RecipientUser { get; set; } 

    public Group RecipientGroup { get; set; } 
} 

有了這個TalkConfiguration類:

class TalkConfiguration : EntityTypeConfiguration<Talk> 
{ 
    public TalkConfiguration() 
    { 
     Property(t => t.StarterUserId).IsRequired(); 
     Property(t => t.RecipientUserId).IsOptional(); 
     Property(t => t.RecipientGroupId).IsOptional(); 
     Property(t => t.DateUtcStarted).IsRequired(); 

     Ignore(t => t.DateStarted); 

     HasRequired(t => t.StarterUser). 
      WithMany(u => u.TalksStarted). 
      HasForeignKey(t => t.StarterUserId); 
     HasOptional(t => t.RecipientUser). 
      WithMany(u => u.InTalks). 
      HasForeignKey(t => t.RecipientUserId); 

     HasOptional(t => t.RecipientGroup).WithOptionalDependent(g => g.GroupTalk); 
    } 
} 

這是Group類:

[DataContract] 
public class Group 
{ 
    [DataMember] 
    public int GroupId { get; set; } 

    [ ... ] 

    public Talk GroupTalk { get; set; } 
} 

GroupConfiguration類:

class GroupConfiguration : EntityTypeConfiguration<Group> 
{ 
    public GroupConfiguration() 
    { 
     [ ... ] // Nothing related to GroupTalk 
    } 
} 

這些類和配置在我的數據庫得到這個Talk表:

enter image description here

我要讓Talk.RecipientGroupIdFOREIGN KEYGroup.GroupId。但是這個模型創建了另一列Talk.RecipientGroup_GroupId作爲FOREIGN KEYGroup.GroupId。而且,我不想那樣。

我該怎麼辦?

回答

1

可選:可選的一對一關係被映射爲獨立關聯,而不是作爲外鍵關聯,這意味着您的模型類中不能包含外鍵屬性。這就是爲什麼你不能在WithOptionalDependent之後鏈接HasForeignKey。而且我很確定RecipientGroupId上的[ForeignKey]屬性被簡單忽略,EF認爲RecipientGroupId是一個普通的標量屬性,沒有任何關係目的。

在數據庫模式本身中,關係有一個外鍵。這是您看到的自動生成的默認名稱:RecipientGroup_GroupId。但不支持將此外鍵映射到屬性。不過,我覺得用MapKey

HasOptional(t => t.RecipientGroup) 
    .WithOptionalDependent(g => g.GroupTalk) 
    .Map(m => m.MapKey("RecipientGroupId")); 

如果你這樣做,你必須刪除TalkRecipientGroupId屬性,您可以重命名列,否則EF會抱怨兩個相互矛盾的列具有相同的名稱。

我相信,可選:可選是唯一的一對一關係是獨立關聯,其他都是外鍵關聯,其中外鍵屬性同時是主鍵屬性(根據Arthur Vickers'回答在this thread的底部)。使用可選:可選關係,這是不可能的,因爲主鍵屬性不能爲空。

由於您的RecipientGroupId具有[DataMember]屬性,因此您希望通過某個服務邊界傳輸該值,因此出於某種原因需要外鍵作爲屬性值。在這種情況下,我將選擇的解決方法是將Talk<->Group關係映射爲類中根本沒有導航屬性的一對多關係(然後使用無參數WithMany()調用映射)或使用集合導航屬性,並確保那麼在業務邏輯中這個集合不能包含多個元素。

+0

感謝您的回答。我不知道我在做什麼。我想表示談話可以有零個或一個小組;也許,可選:可選,不代表那個。 – VansFannel

+0

@VansFannel:如果你還想表示一個'Group'只能參與一個對話或者不說話,那麼你的意圖就是將這個映射爲可選的:可選是很好的。但是,在這種情況下,EF不支持將外鍵作爲屬性公開。如果一個「組」可以參與一個以上的會話映射,那麼一對多的關係會更加適合(而且無論如何映射在技術上更容易)。 – Slauma

相關問題