EF 5 Code First:两个实体之间的一对一和一对多关联
我有两个实体:人员和公司。一个公司有一个或多个联系人(人)。一家公司至少有一个主要联系人(人)。什么是实施这个最好的方法?EF 5 Code First:两个实体之间的一对一和一对多关联
这里是实体:
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。当我一个人作为主要联系人相关联,并加入到为同一家公司的联系人列表,它抛出一个错误:
Unable to determine a valid ordering for dependent operations. Dependencies may exist due to foreign key constraints, model requirements, or store-generated values.
我希望有关实现这样的场景可能的方式回答。
显然Person
不能属于多个公司。所以你可以让Primary
属性为Person
。它降低了模型复杂性:您只需要一对多关联。然而,这增加了业务逻辑的复杂性:(1)你需要获得通过
company.Persons.Where(p => p.IsPrimary).First();
主要联系人这是不一样阅读导航属性一样容易,和(2),你需要的逻辑,以确保只有一个Person
是主要的。
如果要保留当前模型,应先保存公司及其联系人,然后在第二个事务中分配主要联系人。当你在一个事务中执行它时,EF可以同时设置两个生成的外键。它必须首先为公司的FK创建公司,并首先为公司的FK创建公司。
谢谢!听起来不错。我现在正在设计我的模型,所以我不会被迫保留我的模型。如果我遵循您的建议并创建IsPrimary属性,那么确保公司每次只有一个主要联系人的最佳方法是什么?我感谢你的回答! – 2013-02-09 14:05:10
只是“蛮力”:做一个主要的,并检查其他人是否。 – 2013-02-09 15:11:17
谢谢你的帮助。它必须是首先在EF代码中实现此功能的最佳方法。 – 2013-02-16 14:02:24
您的类图有点误导,您有'Company.Contacts',但您的关系线表示它是1对1的关系。一家公司只能有一个联系人和一个主要联系人? – CodingGorilla 2013-02-08 16:25:36
为什么你将PrimaryContact分离出来而不是Person上的字段? – IronMan84 2013-02-08 16:43:54
谢谢@CodingGorilla和IronMan84我已经更新了类图。我将尝试将PrimaryContact关联作为Person上的字段。 – 2013-02-08 17:00:23