Skip to content

Instantly share code, notes, and snippets.

@Deathspike
Created January 20, 2016 09:07
Show Gist options
  • Save Deathspike/77dbd33c781971e36eab to your computer and use it in GitHub Desktop.
Save Deathspike/77dbd33c781971e36eab to your computer and use it in GitHub Desktop.
EF6+ UoW
public class Context : IContext
{
private readonly Entities _entities; // EF6+ DbContext
#region Constructor
static Context()
{
var ensureReference = SqlProviderServices.Instance;
}
public Context()
{
_entities = new Entities();
_entities.Configuration.AutoDetectChangesEnabled = true;
_entities.Configuration.LazyLoadingEnabled = false;
_entities.Configuration.ProxyCreationEnabled = true;
_entities.Configuration.ValidateOnSaveEnabled = true;
}
#endregion
#region Implementation of IContext
public int SaveChanges()
{
try
{
return Math.Max(0, _entities.SaveChanges());
}
catch (DbEntityValidationException ex)
{
throw new ContextException(string.Concat("Validation failed: ", string.Join("; ", ex.EntityValidationErrors
.SelectMany(x => x?.ValidationErrors)
.Select(x => $"{x?.PropertyName}={x?.ErrorMessage}")
.ToArray())), ex);
}
catch (SqlException ex)
{
var innerException = ex as Exception;
while (innerException.InnerException != null) innerException = innerException.InnerException;
throw new ContextException(innerException.Message, ex);
}
}
public IContextMapper<Account> Accounts
{
get { return new ContextMapper<Account>(_entities, _entities.Accounts); }
}
#endregion
#region Implementation of IDisposable
public void Dispose()
{
_entities.Dispose();
}
#endregion
}
public class ContextException : Exception
{
#region Constructor
public ContextException(string message) : base(message)
{
}
public ContextException(string message, Exception exception) : base(message, exception)
{
}
#endregion
}
internal class ContextMapper<T> : IContextMapper<T> where T : Entity
{
private readonly Entities _entities;
private readonly IQueryable<T> _query;
private readonly IDbSet<T> _set;
#region Constructor
public ContextMapper(Entities entities, IDbSet<T> set) : this(entities, set, set)
{
}
public ContextMapper(Entities entities, IQueryable<T> query, IDbSet<T> set)
{
_entities = entities;
_query = query;
_set = set;
}
#endregion
#region Implementation of IContextMapper<T>
public T Create(T entity)
{
_set.Add(entity);
return entity;
}
public T Delete(T entity)
{
_set.Remove(entity);
return entity;
}
public IContextMapper<T> Where(Expression<Func<T, bool>> predicate)
{
return new ContextMapper<T>(_entities, _query.Where(predicate), _set);
}
public IContextMapper<T> With(Expression<Func<T, object>> path)
{
return new ContextMapper<T>(_entities, _query.Include(path), _set);
}
#endregion
#region Implementation of IEnumerable
public IEnumerator<T> GetEnumerator()
{
return _query.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
#region Implementation of IQueryable
public Expression Expression
{
get { return _query.Expression; }
}
public Type ElementType
{
get { return _query.ElementType; }
}
public IQueryProvider Provider
{
get { return _query.Provider; }
}
#endregion
}
internal class ContextMapperNone<T> : IContextMapper<T> where T : Entity
{
private readonly IQueryable<T> _query;
#region Constructor
public ContextMapperNone()
{
_query = Enumerable.Empty<T>().AsQueryable();
}
#endregion
#region Implementation of IContextMapper<T>
public T Create(T entity)
{
return entity;
}
public T Delete(T entity)
{
return entity;
}
public IContextMapper<T> Where(Expression<Func<T, bool>> predicate)
{
return this;
}
public IContextMapper<T> With(Expression<Func<T, object>> path)
{
return this;
}
#endregion
#region Implementation of IEnumerable
public IEnumerator<T> GetEnumerator()
{
return _query.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
#region Implementation of IQueryable
public Expression Expression
{
get { return _query.Expression; }
}
public Type ElementType
{
get { return _query.ElementType; }
}
public IQueryProvider Provider
{
get { return _query.Provider; }
}
#endregion
}
public interface IContext : IDisposable
{
int SaveChanges();
IContextMapper<Account> Accounts { get; }
}
public interface IContextMapper<T> : IQueryable<T> where T : Entity
{
T Create(T entity);
T Delete(T entity);
IContextMapper<T> Where(Expression<Func<T, bool>> predicate);
IContextMapper<T> With(Expression<Func<T, object>> path);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment