2017-10-28 152 views
1

比方说,我有一个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。

+0

这取决于与该例外发生了什么....如果你不处理它,那么用户会得到一个500错误(我认为这是你提到的请求是asp.net)。如果您确实处理了它并且请求继续,那么下次调用savechanges时,将会在同一个dbcontext实例上生成相同的异常。 – Igor

+0

我编辑我的帖子,使其更清晰。 – JeloneK

+1

@JeloneK'DbContext'是* Unit Of Work *模式的一个实现。没有太多意义可以像你一样再次将其包装到另一个工作单元中。这个额外的包装没有任何用处。 – Kostya

回答

-1

正如@Igor在评论中所说的那样,您是否处理了这个异常会产生影响,但是由于您的场景涉及到对同一个请求调用另一个仓库,因此我假设您处理了它。

正如你所说,你会重复使用你的DbContextFactory的同一个实例,这是持有你的DbContext实例的人,可以肯定地说,除非你在其他地方放置了这个工厂,你的上下文仍然会有相同的User实例添加并且因此在另一个存储库上的相同上下文中调用Commit将仍然插入所述用户。