Skip to content

Instantly share code, notes, and snippets.

@Tewr
Created November 8, 2018 20:11
Show Gist options
  • Save Tewr/576e5f386ae37c4b56734c21b646cfeb to your computer and use it in GitHub Desktop.
Save Tewr/576e5f386ae37c4b56734c21b646cfeb to your computer and use it in GitHub Desktop.
Entity framework 6 graph update
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Validation;
using System.Linq;
public interface IEntity
{
int Id { get; set; }
}
public class StateChecker<TEntity>
{
private readonly TEntity _demande;
private readonly TEntity _stored;
private readonly IDbContext _context;
public StateChecker(TEntity demande, TEntity stored, IDbContext context)
{
_demande = demande;
_stored = stored;
_context = context;
}
public StateChecker<TEntity> OwnedEntity<TTarget>(Func<TEntity, TTarget> property,
Action<StateChecker<TTarget>> withChildren = null) where TTarget : class, IEntity
{
var requestForChange = property(_demande);
if (requestForChange == null)
{
var target = property(_stored);
if (target != null)
{
_context.Set<TTarget>().Remove(target);
}
}
else
{
if (withChildren != null)
{
var childStateChecker = new StateChecker<TTarget>(requestForChange, property(_stored), _context);
withChildren(childStateChecker);
}
var isNew = requestForChange.Id == 0;
if (isNew)
{
_context.Set<TTarget>().Add(requestForChange);
}
else
{
_context.Set<TTarget>().Attach(requestForChange);
_context.Entry(requestForChange).State = EntityState.Modified;
}
}
return this;
}
public StateChecker<TEntity> OwnedCollection<TTarget>(Func<TEntity, ICollection<TTarget>> property,
Action<StateChecker<TTarget>> withChildren = null) where TTarget : class, IEntity
{
var requestForChangeCollection = property(_demande);
var storedCollection = property(_stored);
if (requestForChangeCollection == null)
{
throw new ArgumentException(@"Collection in request must not be null", nameof(property));
}
if (storedCollection == null)
{
throw new InvalidOperationException(@"Stored Collection not be null");
}
var storedById = new System.Lazy<Dictionary<int, TTarget>>(() => storedCollection.ToDictionary(x => x.Id));
foreach (var entity in requestForChangeCollection)
{
if (withChildren != null)
{
storedById.Value.TryGetValue(entity.Id, out var storedEntity);
var childStateChecker = new StateChecker<TTarget>(entity, storedEntity, _context);
withChildren(childStateChecker);
}
_context.Entry(entity).State = entity.Id == 0 ? EntityState.Added : EntityState.Modified;
}
var listOfReferencedIds = requestForChangeCollection.Select(x => x.Id).Where(id => id != 0).ToHashSet();
foreach (var storedEntity in storedCollection)
{
if (!listOfReferencedIds.Contains(storedEntity.Id))
{
_context.Set<TTarget>().Remove(storedEntity);
}
}
return this;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment