我一直在推动ADO EF Code First的轮胎,并提出了以下问题:
我的模型很简单地代表了一棵家谱。 它由一个具有一些标量属性FirstName等的Person类组成 代表父母和人的人的集合 另一个代表儿童的人物集合。
public class Person
{
public int id { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public DateTime? DateOfBirth { get; set; }
List<Person> children = new List<Person>();
public IList<Person> Children { get { return children; } set { children = (List<Person>)value; } }
List<Person> parents = new List<Person>();
public IList<Person> Parents { get { return parents; } set { parents = (List<Person>)value; } }
}
上下文代码非常简单
public class DataContext : DbContext
{
public DbSet<Person> People { get; set; }
}
创建的DataBase架构符合预期。 一个人员表与一个名为PersonPersons的表的一对多关系。 (顺便说一句,无论如何将其更改为名为FamilyTree的表?)
然后我继续使用一些数据为数据库播种,这是一个用于热门辛普森一家卡通节目的家谱。 我创建了我需要的所有人,将它们关联起来,然后保存代表Homer Simpson的person变量。
class ProjectDBInitializer : DropCreateDatabaseIfModelChanges<DataContext>
{
protected override void Seed(DataContext context)
{
Person ph = new Person() { FirstName = "Homer", LastName = "Simpson" };
Person pm = new Person() { FirstName = "Marge", LastName = "Simpson" };
Person pb = new Person() { FirstName = "Bart", LastName = "Simpson" };
Person pl = new Person() { FirstName = "Lisa", LastName = "Simpson" };
Person phf = new Person() { FirstName = "GranPa", LastName = "Simpson" };
Person phm = new Person() { FirstName = "GranMa", LastName = "Simpson" };
Person pmf = new Person() { FirstName = "Marge Father", LastName = "Maiden" };
Person pmm = new Person() { FirstName = "Marge Mother", LastName = "Maiden" };
phf.Children.Add(ph);
phm.Children.Add(ph);
ph.Children.Add(pb);
ph.Children.Add(pl);
pb.Parents.Add(ph);
pb.Parents.Add(pm);
pl.Parents.Add(ph);
pl.Parents.Add(pm);
pm.Parents.Add(pmf);
pm.Parents.Add(pmm);
context.People.Add(ph);
context.SaveChanges();
}
}
当我查看DataBase中的内容时,问题就出现了。
所有Marge的家庭都已插入,但荷马的父母(GranPa和GranMa)却没有。 我认为这与ph varibale没有引用它们的事实有关,即使它们在他们的Children集合中持有对它的引用。
解决此问题的最佳(最简单)方法是什么?
答案 0 :(得分:2)
要重新生成表格,您必须为您的上下文添加流畅的映射:
public class DataContext : DbContext
{
public DbSet<Person> People { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Person>()
.HasMany(p => p.Children)
.WithMany(c => c.Parents)
.Map(m => m.ToTable("FamilyTree"));
}
}
插入问题正如您所描述的那样。如果你想插入荷马,你必须将phf和phm设置为他的父母,或者你必须以与添加荷马相同的方式将phm和phf添加到人物设置。
自动生成的POCO对象(用于从EDMX生成POCO的T4模板)使用更复杂的导航属性代码,并在内部处理关系修正,因此如果您将phr中的Homer添加到子集合中,它将自动将phm添加到Homer的父项。如果您想在自己的POCO中使用此类功能,则必须自己实现。 Fixup方法并不总是双赢的解决方案,因为它们有一些缺点,有时会触发延迟加载,而不需要加载数据。