Wie für Entity Framework, sollten Sie nur eine DbContext
in Ihrer Anwendung haben.
Sie können mit einer einfachen Abstraktion von Ihrem Kontext betrachten Sie eine Lese-Seite und eine Schreib-Seite zu geben:
public abstract class Entity
{
// Marker class
}
public interface IEntityReader<out TEntity> where TEntity : Entity
{
IQueryable<TEntity> Query();
}
public interface IEntityWriter<TEntity> where TEntity : Entity
{
TEntity Get(object primaryKey);
void Save(TEntity entity);
void Delete(TEntity entity);
}
Mit der Umsetzung fo diese wie:
internal sealed class EntityFrameworkReader<TEntity> : IEntityReader<TEntity> where TEntity : Entity
{
private readonly Func<DbContext> _contextProvider;
public EntityFrameworkReader(Func<DbContext> contextProvider)
{
_contextProvider = contextProvider;
}
public IQueryable<TEntity> Query()
{
return _contextProvider().Set<TEntity>().AsNoTracking();
}
}
internal sealed class EntityFrameworkWriter<TEntity> : IEntityWriter<TEntity> where TEntity : Entity
{
private readonly Func<DbContext> _contextProvider;
public EntityFrameworkWriter(Func<DbContext> contextProvider)
{
_contextProvider = contextProvider;
}
public void Save(TEntity entity)
{
var context = _contextProvider();
var entry = context.Entry(entity);
// If it is not tracked by the context, add it to the context
if (entry.State == EntityState.Detached)
{
// This also sets the entity state to added.
context.Set<TEntity>().Add(entity);
}
else
{
// Tells the context that the entity should be updated during saving changes
entry.State = EntityState.Modified;
}
// In a perfect world, you should use a decorator and save the changes there using Dependency Injection
context.SaveChanges();
}
public void Delete(TEntity entity)
{
var context = _contextProvider();
var entry = context.Entry(entity);
if (entry.State != EntityState.Deleted)
{
// This also sets the entity state to Deleted.
context.Set<TEntity>().Remove(entity);
}
// In a perfect world, you should use a decorator and save the changes there using Dependency Injection
context.SaveChanges();
}
public TEntity Get(object primaryKey)
{
var context = _contextProvider();
var entity = context.Set<TEntity>().Find(primaryKey);
if (entity == null) return null;
// We found the entity, set the state to unchanged.
context.Entry(entity).State = EntityState.Unchanged;
return entity;
}
}
Wenn Sie mit Eine Abhängigkeitsinjektions-Bibliothek, wie Simple Injector, können Sie wie folgt verdrahten:
container.Register<DbContext, MyDbContext>(Lifestyle.Scoped);
container.Register(typeof(IEntityWriter<>), typeof(EntityFrameworkWriter<>), Lifestyle.Scoped);
container.Register(typeof(IEntityReader<>), typeof(EntityFrameworkReader<>), Lifestyle.Scoped);
Wie würden Sie 'AsNoTracki aktivieren? ng 'kontext-weit? –
Ich denke nicht, dass dies aus der Box kommt, aber es kann getan werden. http://stackoverflow.com/questions/12726878/global-setting-for-asnotracking – user183872