DbContext处置,dbcontext工厂,工作单元
问题描述:
比方说,我有一个DbContextFactory,我在存储库中使用DbContext (我不知道它是最好的解决方案)。DbContext处置,dbcontext工厂,工作单元
public class DbContextFactory : Disposable, IDbContextFactory
{
private readonly Dictionary<Type, System.Data.Entity.DbContext> _dbContexts;
public DbContextFactory()
{
_dbContexts = new Dictionary<Type, System.Data.Entity.DbContext>();
}
public T GetDbContext<T>() where T : System.Data.Entity.DbContext, new()
{
if (!_dbContexts.ContainsKey(typeof(T)))
{
_dbContexts.Add(typeof(T), new T());
}
return _dbContexts[typeof(T)] as T;
}
protected override void DisposeCore()
{
foreach (var kvpDbContext in _dbContexts)
{
kvpDbContext.Value?.Dispose();
}
}
}
,我必须的UnitOfWork我注入在BusinessLogic类
public class UnitOfWork<T> : IUnitOfWork
where T : System.Data.Entity.DbContext, new()
{
private readonly IDbContextFactory _dbContextFactory;
private T _dbContext;
public UnitOfWork(IDbContextFactory dbContextFactory)
{
_dbContextFactory = dbContextFactory;
}
public T DbContext => _dbContext ?? (_dbContext = _dbContextFactory.GetDbContext<T>());
public void Commit()
{
DbContext.SaveChanges();
}
}
比我调用库方法,让我们假定它抛出一个异常:
public void CreateUser(User user)
{
_userRepository.Add(user);
throw new Exception();
UnitOfWork.Commit();
}
发生了什么,如果我打电话其他存储库方法在同一个请求中(或者不要使用工厂作为每个请求的实例),并且该方法成功结束,而UnitOfWork.Commit()将被调用,这是否意味着更改在CreateUser中创建失败的方法也会被保存吗?或者在抛出异常连接关闭之后,并且没有风险保存该方法的更改?
为了更清楚: 我想承载在WCF服务,让我们说单身模式。 然后 - 一个包含多个(例如5个)存储库调用的请求调用方法,前三个将成功,第四个将失败,这意味着我不会在那里调用UnitOfWork.Commit()。 然后其他请求来了,这只是成功。这是否意味着,将保存来自先前方法的前三个存储库调用的更改? 由于单例 - 仍然会有相同的DbContextFactory同样的DbContext。
答
正如@Igor在评论中所说的那样,您是否处理了这个异常会产生影响,但是由于您的场景涉及到对同一个请求调用另一个仓库,因此我假设您处理了它。
正如你所说,你会重复使用你的DbContextFactory的同一个实例,这是持有你的DbContext实例的人,可以肯定地说,除非你在其他地方放置了这个工厂,你的上下文仍然会有相同的User实例添加并且因此在另一个存储库上的相同上下文中调用Commit将仍然插入所述用户。
这取决于与该例外发生了什么....如果你不处理它,那么用户会得到一个500错误(我认为这是你提到的请求是asp.net)。如果您确实处理了它并且请求继续,那么下次调用savechanges时,将会在同一个dbcontext实例上生成相同的异常。 – Igor
我编辑我的帖子,使其更清晰。 – JeloneK
@JeloneK'DbContext'是* Unit Of Work *模式的一个实现。没有太多意义可以像你一样再次将其包装到另一个工作单元中。这个额外的包装没有任何用处。 – Kostya