实体框架和工作单元

Sam*_*Sam 5 entity-framework unit-of-work

我正在使用EF/Repository/Unit of Work,但我很难理解一些细节.在UnitOfWork内部,我创建了一个新的EF DbContext(EmmaContext),但是在存储库中查看,我将其转换为我知道错误,如何正确获取repo中的上下文?也许我完全走错了路?

这是我的UnitOfWork:

//Interface
public interface IUnitOfWork : IDisposable
{
    void Commit();
}

//Implementation
public class UnitOfWork : IUnitOfWork
{
    #region Fields/Properties
    private bool isDisposed = false;
    public EmmaContext Context { get; set; }
    #endregion

    #region Constructor(s)
    public UnitOfWork()
    {
        this.Context = new EmmaContext();
    }
    #endregion

    #region Methods
    public void Commit()
    {
        this.Context.SaveChanges();
    }

    public void Dispose()
    {
        if (!isDisposed)
            Dispose(true);
        GC.SuppressFinalize(this);
    }

    private void Dispose(bool disposing)
    {
        isDisposed = true;
        if (disposing)
        {
            if (this.Context != null)
                this.Context.Dispose();
        }
    }
    #endregion
}
Run Code Online (Sandbox Code Playgroud)

这是存储库:

//Interface
public interface IRepository<TEntity> where TEntity : class
{
    IQueryable<TEntity> Query();
    void Add(TEntity entity);
    void Attach(TEntity entity);
    void Delete(TEntity entity);
    void Save(TEntity entity);
}

//Implementation
public abstract class RepositoryBase<TEntity> : IRepository<TEntity> where TEntity : class
{
    #region Fields/Properties
    protected EmmaContext context;
    protected DbSet<TEntity> dbSet;
    #endregion

    #region Constructor(s)
    public RepositoryBase(IUnitOfWork unitOfWork)
    {
        this.context = ((UnitOfWork)unitOfWork).Context;
        this.dbSet = context.Set<TEntity>();
    }
    #endregion

    #region Methods
    public void Add(TEntity entity)
    {
        dbSet.Add(entity);
    }

    public void Attach(TEntity entity)
    {
        dbSet.Attach(entity);
    }

    public void Delete(TEntity entity)
    {
        dbSet.Remove(entity);
    }

    public IQueryable<TEntity> Query()
    {
        return dbSet.AsQueryable();
    }

    public void Save(TEntity entity)
    {
        Attach(entity);
        context.MarkModified(entity);
    }
    #endregion
}
Run Code Online (Sandbox Code Playgroud)

Ode*_*ode 4

Sam:我通常对具体的存储库在 ctor 中采用具体的工作单元感到满意:

   public RepositoryBase(UnitOfWork unitOfWork)
   {
        this.context = unitOfWork.Context;
        this.dbSet = context.Set<TEntity>();
   }
Run Code Online (Sandbox Code Playgroud)

存储库和 UoW 通常协同工作,并且需要彼此了解一些。

当然,使用这些类的代码只知道接口定义,而不知道具体类型。

  • @Sam - 系统中的控制器或其他组件只需使用 IUnitOfWork 等接口定义即可。只有您的容器知道 IUnitOfWork 映射到 UnitOfWork 并且通常配置到容器中,即使用 StructureMap,您通常有一段启动代码,表示 x.For&lt;IUnitOfWork&gt;().Use&lt;UnitOfWork()。至于测试 - 将使用集成测试而不是单元测试来测试真实的 UoW 和存储库。希望这是有道理的。 (2认同)