.net ADO EF代码第一个双向多对多自参考挑战
我首先在ADO EF代码上对轮胎进行了修改,并提出了以下问题: 我的模型非常简单地代表了一个家谱。 它由一个Person类和一些标量属性FirstName等组成 代表父母和子女的人的集合 另一组代表儿童的人.net ADO EF代码第一个双向多对多自参考挑战,.net,entity-framework-4.1,mapping,many-to-many,entity-relationship,.net,Entity Framework 4.1,Mapping,Many To Many,Entity Relationship,我首先在ADO EF代码上对轮胎进行了修改,并提出了以下问题: 我的模型非常简单地代表了一个家谱。 它由一个Person类和一些标量属性FirstName等组成 代表父母和子女的人的集合 另一组代表儿童的人 public class Person { public int id { get; set; } public string FirstName { get; set; } public string MiddleName { get; set; } pub
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; } }
}
公共类人物
{
公共int id{get;set;}
公共字符串名{get;set;}
公共字符串MiddleName{get;set;}
公共字符串LastName{get;set;}
公共日期时间?出生日期{get;set;}
列表子项=新列表();
公共IList子项{get{return Children;}set{Children=(List)value;}}
列表父项=新列表();
公共IList父项{get{return Parents;}set{Parents=(List)value;}}
}
上下文代码非常简单
public class DataContext : DbContext
{
public DbSet<Person> People { get; set; }
}
公共类DataContext:DbContext
{
公共数据库集人物{get;set;}
}
所创建的数据库架构与预期的一样。
与名为PersonPersons的表具有2个一对多关系的人员表。(顺便问一下,是否要将其更改为名为FamilyTree的表?)
然后,我继续在数据库中植入一些数据,一个流行的辛普森卡通节目的家谱。
我创建所有需要的人,将他们联系起来,然后保存代表荷马·辛普森的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();
}
}
class ProjectDBInitializer:DropCreateDatabaseIfModelChanges
{
受保护的覆盖无效种子(DataContext上下文)
{
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=newperson(){FirstName=“Lisa”,LastName=“Simpson”};
Person phf=newperson(){FirstName=“GranPa”,LastName=“Simpson”};
Person phm=new Person(){FirstName=“GranMa”,LastName=“Simpson”};
Person pmf=newperson(){FirstName=“Marge-Father”,LastName=“Maiden”};
Person pmm=new Person(){FirstName=“Marge Mother”,LastName=“Maiden”};
phf.儿童。添加(ph);
phm。儿童。添加(ph);
添加(pb);
儿童医学博士(pl);
pb.父母添加(ph);
pb.Parents.Add(pm);
pl.添加(ph);
pl.Parents.Add(pm);
pm.Parents.Add(pmf);
pm.Parents.Add(pmm);
context.People.Add(ph);
SaveChanges();
}
}
当我查看数据库中的内容时,问题就出现了
玛吉的家人都被安插进去了,但荷马的父母(格兰帕和格兰玛)没有。
我认为这与这样一个事实有关,即ph varibale没有提及他们,即使他们在他们的儿童收藏中有提及
解决此问题的最佳(最简单)方法是什么?要重新命名表格,必须向上下文添加流畅的映射:
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"));
}
}
公共类DataContext:DbContext
{
公共数据库集人物{get;set;}
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
基于模型创建(modelBuilder);
modelBuilder.Entity()
.HasMany(p=>p.Children)
.有许多(c=>c.父母)
.Map(m=>m.ToTable(“家庭树”);
}
}
insert的问题正是您所描述的。如果要插入荷马,必须将phf和phm设置为其父项,或者必须以添加荷马的相同方式将phm和phf添加到人员集
自动生成的POCO对象(用于从EDMX生成POCO的T4模板)对导航属性使用更复杂的代码,它们在内部处理关系修复,因此,如果将Homer添加到phm中的子集合中,它将自动将phm添加到Homer的父集合中。如果您想在自己的POCO中实现这样的功能,您必须自己实现。修复方法并不总是双赢的解决方案,因为它们有一些缺点,有时会触发延迟加载,而不需要实际加载数据。我对Ladislav的答案没有更多补充,请阅读并接受它作为答案:)非常感谢您的回复。就像我担心的那样!我需要写更多的代码。我研究了POCO类正在做什么,将其放入模板是有意义的。这是重复和无聊的:)这表示我很惊讶代码优先引擎没有提供任何处理问题的功能,因为它正确地推断了关系,当然它可以实现某种图形遍历来修复关系,然后再提交给DB。我自己来试一试。干杯