Мне не удалось придумать метод сброса глобального DbContext. Однако я смог решить свою проблему, внедрив DbContextLocator
в любой класс, которому нужен DbContext, вместо передачи самого DbContext.
Моя цель состояла в том, чтобы поддерживать глобальный DbContext, но разрешать его сброс при необходимости (например, после перестройки или импорта базы данных).
Мое решение использует абстрактный базовый класс и конкретный класс.
Базовый класс
using System.Data.Entity;
namespace CommonLibrary.Database
{
public abstract class DbContextLocator
{
private DbContext _dbContext;
public DbContext Current
{
get { return _dbContext; }
}
public DbContextLocator()
{
_dbContext = GetNew();
}
public virtual void Reset()
{
_dbContext.Dispose();
_dbContext = GetNew();
}
protected abstract DbContext GetNew();
}
}
Класс бетона
using System.Data.Entity;
using CommonLibrary.Database;
using ExperimentBase.EntityModels;
namespace MainProject.Models
{
public class MainDbContextLocator : DbContextLocator
{
public new MainDbContext Current
{
get { return (MainDbContext)base.Current; }
}
protected override DbContext GetNew()
{
return new MainDbContext();
}
}
}
Использование
Получить текущий DbContext:
var dbContext = dbContextLocator.Current;
Сброс DbContext:
dbContextLocator.Reset();
//Note: normally followed by code that re-initializes app data
Редактировать
Основываясь на отзывах Шимми, я превратил DbContextLocatorBase
в универсальный. (Я также сейчас реализую IDisposable
.)
Базовый класс
public class DbContextLocator<TContext> : IDisposable
where TContext : DbContext, new()
{
private TContext _dbContext;
public TContext Current
{
get { return _dbContext; }
}
public DbContextLocator()
{
_dbContext = GetNew();
}
public virtual void Reset()
{
_dbContext.Dispose();
_dbContext = GetNew();
}
protected virtual TContext GetNew()
{
return new TContext();
}
public void Dispose()
{
_dbContext.Dispose();
}
}
Класс бетона (необязательно, поскольку базовый класс больше не является абстрактным)
public class MainDbContextLocator : DbContextLocator<MainDbContext> { }