我没能拿出来重置全局的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> { }
我想说'DbContextLocator'是一个泛型类,即'DbContextLocator where TContext:DbContext',那么你不必做派生类,或者你可以让派生类只是为了减少冗长而不声明任何东西它,见示例[这里](http://pastebin.com/KRqQvAie) –
Shimmy
2012-05-03 22:06:51
好主意......我想我从来没有优化到这一点,因为我只倾向于写每个项目的具体类之一。 – devuxer 2012-05-03 22:28:18
一旦你习惯了泛型,这不是一个优化,这是默认的代码设计:) – Shimmy 2012-05-03 22:55:57