我有一个实体框架模型,它有3个表(每个表都有缩进主键)。根表与子表具有1对多的关系,该子表与其子表具有1对多的关系。此模型在从数据库生成的模型中正确反映。
在代码中,我们在父表中插入(添加),然后插入那些子表,最后我们对子项的子进行插入。代码看起来类似于以下示例:
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如何维护这些对象的关系?这些插入物是否安全?这是否会导致孤儿或儿童被插入错误的父母(现在我们没有看到这种情况发生但是它有潜力)?
谢谢!
已编辑(更正):
代码已更新,以反映父插入是在所有子项插入后发生的。
答案 0 :(得分: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.