EF6 - 一个用于保存所有其他表的联系人的表

时间:2014-07-23 15:43:40

标签: c# database entity-framework entity-framework-6 composite-primary-key

好的,我知道这个很奇怪,但我试图将所有联系人放在一张桌子上;每个表都将使用该表中的其他表的名称和ID与另一个表相关。例如,联系 FRED与表格#34;公司"使用CompanyID 3 ,而联系人 BARNEY与表"会计师"使用AccountantID 21

public class Contact: DbContext
{
    [Key, Column(Order = 0)]
    public string TableName { get; set; }

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

    public string ContactName { get; set; }  
}

public class Company: DbContext
{
  [Key]
  public int CompanyID { get; set; }

  public string CompanyName { get; set; }  

  public virtual List<Contact> Contacts { get; set; }
}

public class Accountant: DbContext
{
  [Key]
  public int AccountantID { get; set; }

  public string AccountantName { get; set; }  

  public virtual List<Contact> Contacts { get; set; }
}

因此外键不起作用,但复合键(TableName / ReferenceID)将是唯一的,因此公司可以包含相关联系人列表(TableName为&#34;公司&#34) ;以及与CompanyID匹配的ReferenceID)。我觉得我必须设置这样的模型构建器,但是我真的不确定它在这种特殊情况下是如何工作的......

modelBuilder.Entity<Company>()
            .WithMany(e => e.Contacts)
            .HasOptional(d => new { "Company", d.ReferenceID } )
            .WillCascadeOnDelete(true);

我打算称自己为 EntityFrameworkNewbie ,所以请原谅任何明显的疏忽。感谢。

2 个答案:

答案 0 :(得分:1)

这不是你能够以你想要的方式在EF中做的事情,有很多方法,我的建议是多对多的关系(见http://msdn.microsoft.com/en-gb/data/jj591620.aspx):

modelBuilder.Entity<Company>() 
.HasMany(t => t.Contacts) 
.WithMany(t => t.Companies) 
.Map(m => 
{ 
    m.ToTable("CompanyContacts"); 
    m.MapLeftKey("ContactID"); 
    m.MapRightKey("CompanyID"); 
});

modelBuilder.Entity<Accountant>() 
.HasMany(t => t.Contacts) 
.WithMany(t => t.Accountants) 
.Map(m => 
{ 
    m.ToTable("AccountantContacts"); 
    m.MapLeftKey("ContactID"); 
    m.MapRightKey("AccountantID"); 
});

从技术上讲,在db术语中,这意味着您可以让一个人成为多个客户的联系人,或者一个人同时成为客户和会计师的联系人。这是其中一个没有正确答案的情况之一。

另一个选项是TablePerType继承(因此您将创建一个CompanyContact和一个AccountantContact对象,这两个对象都继承自联系人(http://weblogs.asp.net/manavi/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-2-table-per-type-tpt

答案 1 :(得分:0)

不要这样做。这不是一个好的关系设计,并且不会为您提供引用完整性,这是首先使用关系数据库的主要好处。

如果每个相关实体只能有一个联系人,只需将contactId放在相关实体上即可。如果相关实体可以有多个联系人,请创建一个正确表示此情况的m:n表(例如,CompanyContact表)。