Reputation: 2577
I have an Entity Framework model that has 3 tables (each with indentity primary keys). The root table has a 1 to many relationship to a child table, that child table has a 1 to many relationship with it's child table. This model is reflected correctly in the model that was generated from the database.
In code, we do an Insert (Add) into the parent table, we then do an insert of that children's tables, and then finally we do inserts on the children's children. The code looks similar to the example below:
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)
}
The inserts into the database seem to be working. However, what I would like to understand is under the hood how does EF maintain the relationship of these objects without me explicitly defining the foreign key relationship during the mapping? Is these inserts scope safe? Will this cause orphans or children being inserted into the wrong parent (right now we don't see this happening but does it have the potential)?
Thanks!
EDITED (CORRECTION):
The code has been updated to reflect that the parent insert is happening AFTER all the children inserts.
Upvotes: 0
Views: 949
Reputation: 3477
For the entities to be tracked properly by EF you need to have properties that represent relationships between entities. You parent entity should have a property referencing children and children in turn should have properties referencing their children. For example:
class ParentEntity {
public int Id { get; set; }
public ICollection<ChildEntity> Children { get; set; }
}
class ChildEntity {
public int Id { get; set; }
}
As long as you add child entities to parent's Children collection EF can keep track of relationships:
var parent = new ParentEntity();
parent.Children.Add(new ChildEntity());
parent.Children.Add(new ChildEntity());
EF knows that object references in parent.Children collection represent new entities (entities not attached to the context) and will handle them accordingly. The actual inserts to the database don't happen until you call SaveChanges(). When you add an object to DbSet EF just begins to keep track of it in memory. Only when you call SaveChanges() entities will be written to the database. At this point EF will figure out that parent entity needs to be saved first. It will then use parent entity's PK as FK in your child entities. Now you can add parent to context and this will also add children:
context.Set<ParentEntity>().Add(parent);
context.SaveChanges(); // adds parent and two children.
Upvotes: 1