EF 5 Code First:两个实体之间的一对一和一对多关联

时间:2013-02-08 16:09:07

标签: c# .net entity-framework ef-code-first entity-framework-5

我有两个实体:人和公司。公司有一个或多个联系人(人)。公司至少有一个主要联系人(人)。实现这个的最佳方法是什么?

enter image description here

以下是实体:

public class Person
{
    public int PersonId { get; set; }
    public string PersonName { get; set; }
}
public class Company
{
    public int CompanyId { get; set; }
    public string CompanyName { get; set; }
    public virtual ICollection<Person> Contacts { get; set; }
    public int PrimaryContactId { get; set; }
    [ForeignKey("PrimaryContactId")]
    public virtual Person PrimaryConctact { get; set; }
}

背景和初始化:

public class TolleContext : DbContext
{
    public DbSet<Company> Companies { get; set; }
    public DbSet<Person> Persons { get; set; }
    public TolleContext()
    {
        Database.SetInitializer(new TolleContextInitializer());
    }
}
public class TolleContextInitializer : DropCreateDatabaseAlways<TolleContext>
{
    protected override void Seed(TolleContext context)
    {
        var p1 = context.Persons.Add(new Person { PersonName = "Anatoly" });
        var p2 = context.Persons.Add(new Person { PersonName = "Johannes" });
        var contacts = new List<Person> {p1, p2};
        var company = new Company
            {
                CompanyName = "Bool", 
                PrimaryConctact = p1, 
                Contacts = contacts
            };
        context.Companies.Add(company);
        context.SaveChanges();

        base.Seed(context);
    }
}

如果我将某个人与公司的PrimaryContact相关联,则它不会出现在公司。联系人中。当我将某人关联为主要联系人并添加到同一公司的联系人列表时,会引发错误:

  

无法确定相关操作的有效排序。   由于外键约束,模型可能存在依赖关系   要求或商店生成的值。

我希望得到关于实施此类方案的可能方式的答案。

1 个答案:

答案 0 :(得分:1)

显然Person不能属于多家公司。因此,您可以将Primary设为Person的属性。它降低了模型的复杂性:您只需要一对多的关联。但是,它会增加业务逻辑的复杂性:(1)您需要通过

获得主要联系人
company.Persons.Where(p => p.IsPrimary).First();

这不像读取导航属性那么容易,(2)您需要逻辑来确保只有一个Person是主要的。

如果要保留当前模型,则应首先保存公司及其联系人,然后在第二个事务中分配主要联系人。当您在一个事务中执行此操作时,EF可以同时设置两个生成的外键。它必须首先为FK in Person创建公司,并且首先为FK in Company创建公司。