2011-08-11 45 views
4

再一次使用無法更改的遺留數據庫以及使用Entity Framework 4.1和Fluent API僅讀取數據。一對多帶有連接表和一個可選關係的實體框架4.1 Fluent API

public class Client 
{ 
    [Key] 
    public int ClientID { get; set; } 
    public string Name { get; set ;} 

    public virtual ICollection<Phone> Phones { get; set; } 
} 

public class Phone 
{ 
    [Key] 
    public int PhoneID { get; set; } 
    public string Number { get; set; } 

    public virtual Client Client { get; set; } 
} 

public class ClientPhone 
{ 
    [Key] 
    [Column(Order=0)] 
    public int ClientID { get; set; } 

    [Key] 
    [Column(Order=1)] 
    public int PhoneID { get; set; } 
} 

我希望客戶端有很多電話,但電話應該只有一個可選的客戶端。 注意:電話應該只有0 | 1個客戶端。我不想要很多。 所以我嘗試了以下內容:「在類型每個屬性名稱必須是唯一的」

modelBuilder.Entity<Client>() 
    .HasMany(c => c.Phones) 
    .WithOptional(p => p.Client) 
    .Map(m => 
    { 
     m.MapKey("ClientID"); 
     m.ToTable("ClientPhone"); 
    }); 

modelBuilder.Entity<Phone>() 
    .HasOptional(p => p.Client) 
    .WithMany(c => c.Phones) 
    .Map(m => 
    { 
     m.MapKey("PhoneID"); 
     m.ToTable("ClientPhone"); 
    }); 

我試過一對夫婦排列通常獲取有關錯誤的

感謝您的幫助。

使用答案

編輯這裏是我的實體類所做的修改。可以從一個客戶端導航到多個電話和從一個電話到一個客戶端,但是您必須通過ClientPhone連接表。

[Table("Client")] 
public class Client 
{ 
    [Key] 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public int ClientID { get; set; } 

    public string Name { get; set ;} 

    public virtual ICollection<Phone> Phones { get; set; } // Client has * Phones 
} 

[Table("Phone")] 
public class Phone 
{ 
    [Key] 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public int PhoneID { get; set; } 

    public string Number { get; set; } 

    public virtual Client Client { get; set; } // Phone has 0|1 Client 
} 

[Table("ClientPhone")] 
public class ClientPhone 
{ 
    // Removed the Key attribute 
    public int ClientID { get; set; } 

    [Key] // Left the Key on the 0|1 side 
    [ForeignKey("Phone")] 
    public int PhoneID { get; set; } 

    public virtual Client Client { get; set; } // One Client 
    public virtual Phone Phone { get; set; } // One Phone 
} 
+0

您的表格是如何定義的?你在數據庫中擁有哪些表格以及配置了哪些關係?如果數據庫包含多對多和聯結表,則不能將它映射爲一對多。 –

回答

3

您不需要在這裏指定電話和客戶端之間的關係兩次。只使用這樣的一個。

modelBuilder.Entity<Client>().HasMany(c => c.Phones).WithMany(i => i.Clients) 
       .Map(t => t.MapLeftKey("PhoneID") 
        .MapRightKey("ClientID") 
        .ToTable("ClientPhone")); 

你不需要有模型映射關係的表像「ClientPhone」因爲。如果你有一箇舊的數據庫,你可以定製你的映射在我的答案EF會照顧它。正如@Ladislav Mrnka所說的,在數據​​庫級別的一對多關係中,你不想爲關係保留一個單獨的表。爲此,

public class Client 
{ 
    [Key] 
    public int ClientID { get; set; } 
    public string Name { get; set ;} 

    public virtual ICollection<Phone> Phones { get; set; } 
} 

public class Phone 
{ 
    [Key] 
    public int PhoneID { get; set; } 
    public string Number { get; set; } 

    public virtual Client Client { get; set; } 
} 

這對EF來說足夠了。它會創建兩個表clientId電話表保持關係。

問題是你有關係的單獨的表在舊版database.I認爲傳統數據庫的許多一對多relationship.Think兩次域邏輯再定義。

如果你想保持一對多的關係,我認爲你可以在域級別定義多對多的關係(電話有許多客戶端和客戶端在模型類中有很多電話),在你的業務層添加驗證只保留一個客戶端電話

+0

我更新了問題,以便更明確...我需要手機只有0 | 1個客戶端。 – GoClimbColorado

+0

我編輯了我的答案。 –

+0

感謝Jayantha的全面回答。在這和@Ladislav Mrnka答案之間,答案是完整的。我相信我發佈的解決方案適用於我的情況,但您的答案仍然可能。 – GoClimbColorado

1

一對多關係沒有連接(結)表。如果您的數據庫使用聯結表將客戶端連接到電話,則必須使用@Jayantha描述的多對多關係(電話可以有許多客戶端)。

+0

我想我已經按照自己的方案工作了,但問題並不十分清楚。您可以使用連接表在一側製作一對多,另一側製作一對一,這正是我想要做的。 – GoClimbColorado

+0

在這種情況下,聯結表是完全多餘的。 –

+0

我添加了我的解決方案,並很樂意學習如何刪除冗餘,並改進我的嘗試。 – GoClimbColorado

相關問題