DbContext配置,dbcontext工厂,工作单元

时间:2017-10-28 11:08:00

标签: c# entity-framework dbcontext

让我们说我在存储库中使用的DbContextFactory来获取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。

1 个答案:

答案 0 :(得分:-1)

正如@Igor在评论中所说,无论你是否处理该异常都有所不同,但由于你的场景涉及在同一个请求上调用anothet存储库,我假设你确实处理了它。

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