【发布时间】:2013-12-12 18:22:36
【问题描述】:
我的应用程序越来越大,到目前为止,我只有一个 MyDbContext,其中包含我应用程序中需要的所有表。我希望(为了概述)将它们分成多个DbContext,例如MainDbContext、EstateModuleDbContext、AnotherModuleDbContext 和UserDbContext。
我不确定这是如何完成的,因为我现在正在使用依赖注入 (ninject) 将我的 DbContext 放在我的 UnitOfWork 类上,例如:
kernel.Bind(typeof(IUnitOfWork)).To(typeof(UnitOfWork<MyDbContext>));
我是否应该放弃这种依赖注入的方法并明确设置我希望在我的服务上使用的DbContext,例如:
private readonly EstateService _estateService;
public HomeController()
{
IUnitOfWork uow = new UnitOfWork<MyDbContext>();
_estateService = new EstateService(uow);
}
代替:
private readonly EstateService _estateService;
public HomeController(IUnitOfWork uow)
{
_estateService = new EstateService(uow);
}
或者这还有其他更好的方法吗?另外作为一个附带问题,我不喜欢将uow 传递给我的服务 - 还有另一种(更好的)方法吗?
代码
我有这个 IDbContext 和 MyDbContext:
public interface IDbContext
{
DbSet<T> Set<T>() where T : class;
DbEntityEntry<T> Entry<T>(T entity) where T : class;
int SaveChanges();
void Dispose();
}
public class MyDbContext : DbContext, IDbContext
{
public DbSet<Table1> Table1 { get; set; }
public DbSet<Table2> Table1 { get; set; }
public DbSet<Table3> Table1 { get; set; }
public DbSet<Table4> Table1 { get; set; }
public DbSet<Table5> Table1 { get; set; }
/* and so on */
static MyDbContext()
{
Database.SetInitializer<MyDbContext>(new CreateDatabaseIfNotExists<MyDbContext>());
}
public MyDbContext()
: base("MyDbContext")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
}
}
然后我有这个 IRepository 和实现:
public interface IRepository<T> where T : class
{
IQueryable<T> GetAll();
void Add(T entity);
void Delete(T entity);
void DeleteAll(IEnumerable<T> entity);
void Update(T entity);
bool Any();
}
public class Repository<T> : IRepository<T> where T : class
{
private readonly IDbContext _context;
private readonly IDbSet<T> _dbset;
public Repository(IDbContext context)
{
_context = context;
_dbset = context.Set<T>();
}
public virtual IQueryable<T> GetAll()
{
return _dbset;
}
public virtual void Add(T entity)
{
_dbset.Add(entity);
}
public virtual void Delete(T entity)
{
var entry = _context.Entry(entity);
entry.State = EntityState.Deleted;
_dbset.Remove(entity);
}
public virtual void DeleteAll(IEnumerable<T> entity)
{
foreach (var ent in entity)
{
var entry = _context.Entry(ent);
entry.State = EntityState.Deleted;
_dbset.Remove(ent);
}
}
public virtual void Update(T entity)
{
var entry = _context.Entry(entity);
_dbset.Attach(entity);
entry.State = EntityState.Modified;
}
public virtual bool Any()
{
return _dbset.Any();
}
}
以及处理使用 DbContext 完成的工作的 IUnitOfWork 和实现
public interface IUnitOfWork : IDisposable
{
IRepository<TEntity> GetRepository<TEntity>() where TEntity : class;
void Save();
}
public class UnitOfWork<TContext> : IUnitOfWork where TContext : IDbContext, new()
{
private readonly IDbContext _ctx;
private readonly Dictionary<Type, object> _repositories;
private bool _disposed;
public UnitOfWork()
{
_ctx = new TContext();
_repositories = new Dictionary<Type, object>();
_disposed = false;
}
public IRepository<TEntity> GetRepository<TEntity>() where TEntity : class
{
// Checks if the Dictionary Key contains the Model class
if (_repositories.Keys.Contains(typeof(TEntity)))
{
// Return the repository for that Model class
return _repositories[typeof(TEntity)] as IRepository<TEntity>;
}
// If the repository for that Model class doesn't exist, create it
var repository = new Repository<TEntity>(_ctx);
// Add it to the dictionary
_repositories.Add(typeof(TEntity), repository);
return repository;
}
public void Save()
{
_ctx.SaveChanges();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (this._disposed) return;
if (disposing)
{
_ctx.Dispose();
}
this._disposed = true;
}
}
【问题讨论】:
-
是否有任何逻辑接缝可以将数据拆分到多个 dbcontexts 上?如果这样做,您将无法拥有跨上下文的导航或集合属性(例如,您无法在 MainDbContext 中的实体与 UsersDbContext 中的另一个实体之间建立 EF 关系)。
-
无论如何要拆分上下文的原因是什么?此外,如果您拆分它们,则不能使用 DI。我也不喜欢你的工作单元中有存储库(字典的东西)
-
我将在我的应用程序中拥有多个模块,只是为了不让大量模块 DbSet 污染 MyDbContext。也许我应该忽略它?
-
嗨,丹,你能提出一个更好的方法吗?我愿意接受建议
-
我想这样做是因为 'IdentityDbContext' (MVC5 & OWIN) 包含我的 'AppDbContext' 的事务。 UserManager 很实用,但在更改两者之间松散耦合的关系数据时,我想要更多的控制。
标签: c# entity-framework repository-pattern dbcontext unit-of-work