Skip to content

Instantly share code, notes, and snippets.

@flakey-bit
Last active May 29, 2019 22:45
Show Gist options
  • Save flakey-bit/eea47a27b605734104ece5531bb8fcb3 to your computer and use it in GitHub Desktop.
Save flakey-bit/eea47a27b605734104ece5531bb8fcb3 to your computer and use it in GitHub Desktop.
EntityFramework Upsert parent and children
public void Upsert(ParentEntity parentEntity) {
ParentEntity existing = DB.Parents.Find(parentEntity.Id);
if (existing == null) {
DB.Parents.Add(parentEntity);
} else {
var newChildKeys = new HashSet<int>(parentEntity.Children.Select(m => m.Id));
var existingChildren = DB.Children.Where(m => m.ParentId == parentEntity.Id).ToArray();
var existingChildrenKeys = new HashSet<int>(existingChildren.Select(m => m.Id));
foreach (var existingChild in existingChildren) {
if (newChildKeys.Contains(existingChild.Id)) {
DB.Entry(existingChild).State = EntityState.Detached;
} else {
DB.Children.Remove(existingChild);
}
}
foreach (var child in parentEntity.Children) {
child.ParentId = parentEntity.Id;
if (existingChildrenKeys.Contains((child.Id))) {
DB.Children.Attach(child);
DB.Entry(child).State = EntityState.Modified;
} else {
DB.Children.Add(child);
}
}
DB.Entry(existing).State = EntityState.Detached;
DB.Parents.Attach(parentEntity);
DB.Entry(parentEntity).State = EntityState.Modified;
}
SaveChanges();
}
@flakey-bit
Copy link
Author

The basic idea is

  • Find the common keys across the entities (existing in database vs replacement entity)
  • For common keys, detach the old entity, attach the new entity & mark as modified
  • For keys that no-longer exist - remove the entity
  • For new keys - add the entity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment