2012-09-24 151 views
0

我有一个实体框架模型,有3个表(每个都有缩进主键)。根表与子表具有一对多关系,该子表与子表具有一对多的关系。该模型在从数据库生成的模型中正确反映。实体框架4.1关系和插入?

在代码中,我们对父表执行Insert(Add),然后插入那些子表的表格,最后我们插入到子表的子表中。该代码看起来类似于下面的示例:

foreach(var parentItemDTO in someDTOCollection) { 
    foreach(var someChildDTOItem in someChildDTOCollection) { 
     // Do some mapping here to the childEntity from DTO 
     // The foreign key relationship isn't set during mapping. 

     childTable.Insert(childEntity); // Underlying code is _dbSet.Add(entity) 

     foreach(var someChildChildDTOItem in someDTOChildChildCollection) { 
      // Do some mapping here to childChildEntity from DTO 
      // The foreign key relationship isn't set during mapping. 

      childChildTable.Insert(childChildEntity); // Underlying code is _dbSet.Add(entity) 
     } 
    } 

    // Do mapping here of the parentEntity from DTO 

    parentTable.Insert(someEntity); // Underlying code is _dbSet.Add(entity) 
} 

插入数据库似乎工作。但是,我想要了解的是,在映射过程中,EF如何保持这些对象的关系,而无需明确定义外键关系?这些插入范围是否安全?这是否会导致孤儿或孩子被插入错误的父母(现在我们没有看到这种情况发生,但它是否有潜力)?

谢谢!

编辑(校正):

的代码已被更新,以反映父插件发生后所有的孩子插件。

+1

哦,肖恩,实际插入不发生,直到你调用的SaveChanges()。当您将对象添加到DbSet时,EF只会开始在内存中跟踪它,只有当您保存所有实体时才会写入数据库。此时,EF会发现父实体需要首先被保存,而不是将其PK用作子实体中的FK。这是你想知道的吗? – LeffeBrune

回答

1

对于要由EF正确跟踪的实体,您需要具有表示实体之间关系的属性。您的父母实体应该有一个引用儿童的属性,而儿童则应该拥有引用其子女的属性。例如:

class ParentEntity { 
    public int Id { get; set; } 
    public ICollection<ChildEntity> Children { get; set; } 
} 

class ChildEntity { 
    public int Id { get; set; } 
} 

只要你添加子实体父母的孩子集合EF可以跟踪的关系:

var parent = new ParentEntity(); 
parent.Children.Add(new ChildEntity()); 
parent.Children.Add(new ChildEntity()); 

EF知道在parent.Children集合对象引用代表新的实体(实体不附在上下文中)并将相应地处理它们。除非调用SaveChanges(),否则实际插入数据库不会发生。当你添加一个对象到DbSet时,EF刚开始跟踪它在内存中的位置。只有当你调用SaveChanges()实体时才会写入数据库。此时,EF会发现需要首先保存父实体。然后它会在您的子实体中使用父实体的PK作为FK。现在你可以添加父上下文,这也将增加儿童:

context.Set<ParentEntity>().Add(parent); 
context.SaveChanges(); // adds parent and two children. 
+0

POCOs确实在其中定义了集合,并且子集确实也在其中定义了父实体。然而,第二部分没有出现在我们的代码中(最后一部分是),但我们的子实体仍然正在正确地插入,并且父主键作为子表中的外键。这里还有其他的东西在我们失踪?引擎盖下正在发生什么?注:更新代码以反映该插入的父项插入子项后发生(这是在上下文中.DbSet )。 – Sean

+0

如果您将子实体添加到父级集合,或者将子级父级引用设置为父实体EF,则可以计算出您的关系。当您保存父项时,它将跟随.net对象引用并发现所有依赖实体并正确插入它们。 – LeffeBrune

+0

好的。这解释了它!谢谢。 – Sean