2

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

在此处输入图像描述

以下是实体:

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为公司的成员,它不会出现在 company.Contacts 中。当我将某人关联为主要联系人并添加到同一公司的联系人列表时,它会引发错误:

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

我将不胜感激有关实现此类场景的可能方法的答案。

4

1 回答 1

1

显然 aPerson不能属于多个公司。所以你可以制作Primary一个Person. 它降低了模型的复杂性:您只需要一对多的关联。但是,它增加了业务逻辑的复杂性:(1)您需要通过以下方式获取主要联系人

company.Persons.Where(p => p.IsPrimary).First();

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

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

于 2013-02-09T12:16:15.853 回答