我有两个实体:人和公司。公司有一个或多个联系人(人)。公司至少有一个主要联系人(人)。实现这个的最佳方法是什么?
以下是实体:
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
相关联,则它不会出现在公司。联系人中。当我将某人关联为主要联系人并添加到同一公司的联系人列表时,会引发错误:
无法确定相关操作的有效排序。 由于外键约束,模型可能存在依赖关系 要求或商店生成的值。
我希望得到关于实施此类方案的可能方式的答案。
答案 0 :(得分:1)
显然Person
不能属于多家公司。因此,您可以将Primary
设为Person
的属性。它降低了模型的复杂性:您只需要一对多的关联。但是,它会增加业务逻辑的复杂性:(1)您需要通过
company.Persons.Where(p => p.IsPrimary).First();
这不像读取导航属性那么容易,(2)您需要逻辑来确保只有一个Person
是主要的。
如果要保留当前模型,则应首先保存公司及其联系人,然后在第二个事务中分配主要联系人。当您在一个事务中执行此操作时,EF可以同时设置两个生成的外键。它必须首先为FK in Person创建公司,并且首先为FK in Company创建公司。