Skip to content

Instantly share code, notes, and snippets.

@ryanohs
Last active June 15, 2016 02:33
Show Gist options
  • Save ryanohs/1ad56b2eb68cf6707c04ebb1e9b86f83 to your computer and use it in GitHub Desktop.
Save ryanohs/1ad56b2eb68cf6707c04ebb1e9b86f83 to your computer and use it in GitHub Desktop.
For updating database from disconnected entities.
public static class EFHelpers
{
/// <summary>
/// Helper function to update an EF model child collection from a view model posted from javascript.
/// </summary>
public static void MergeGraph<TModel, TUpdate, TId>(
ICollection<TModel> modelCollection,
ICollection<TUpdate> updateCollection,
DbSet<TModel> dbSet,
Func<TModel, TId> modelId,
Func<TUpdate, TId> updateId,
Action<TModel, TUpdate> updateCallback)
where TModel : class, new()
{
var addedOptions = updateCollection.Where(o => modelCollection.All(d => !EqualityComparer<TId>.Default.Equals(modelId(d), updateId(o)))).ToList();
var removedOptions = modelCollection.Where(o => updateCollection.All(d => !EqualityComparer<TId>.Default.Equals(modelId(o), updateId(d)))).ToList();
var updatedOptions = updateCollection.Except(addedOptions).ToList();
foreach (var added in addedOptions)
{
var option = new TModel();
updateCallback(option, added);
modelCollection.Add(option);
}
foreach (var removed in removedOptions)
{
dbSet.Remove(removed);
modelCollection.Remove(removed);
}
foreach (var update in updatedOptions)
{
var original = modelCollection.FirstOrDefault(o => EqualityComparer<TId>.Default.Equals(modelId(o), updateId(update)));
if (original != null)
{
updateCallback(original, update);
}
}
}
}
public ActionResult Save(Parent updated)
{
var model = context.// load from database
EFHelpers.MergeGraph(
model.Children, // the collection to update
updated.Children, // the posted changes
context.Children, // the DbSet for the collection entities
c => c.ChildId, // a selector for the ID or matching key property on the model entity
c => c.ChildId, // a selector for the ID or matching key property on the posted entity
UpdateChild // a function to update an individual child entity
);
}
public void UpdateChild(Child model, Child updated)
{
// update child logic
model.SomeProp = updated.SomeProp;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment