【问题标题】:Entity Framework and Unit of Work实体框架和工作单元
【发布时间】:2012-08-28 20:20:46
【问题描述】:

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

这是我的工作单元:

//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
}

这里是存储库:

//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
}

【问题讨论】:

    标签: entity-framework unit-of-work


    【解决方案1】:

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

       public RepositoryBase(UnitOfWork unitOfWork)
       {
            this.context = unitOfWork.Context;
            this.dbSet = context.Set<TEntity>();
       }
    

    存储库和 UoW 通常协同工作,需要相互了解一点。

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

    【讨论】:

    • 这基本上是我所做的,添加了一个IUnitOfWork接口,但至于单元测试你怎么看?您真的要对您的存储库和工作单元进行单元测试吗?
    • 经过一番思考后,我想知道您是如何将实现抽象到调用代码的同时仍将上下文从 IoC 容器获取到 repo 中的?你有代码示例吗?谢谢!顺便说一句 - 我刚刚读了你的 MVC 3.0 书,很棒的书!
    • @Sam - 系统中的控制器或其他组件只能使用 IUnitOfWork 等接口定义。只有您的容器会知道 IUnitOfWork 映射到 UnitOfWork 并且通常配置到容器中,即使用 StructureMap 您通常有一段启动代码,上面写着 x.For().Use
    【解决方案2】:

    这是best article I've read

    在他们的示例中,他们像这样管理存储库:

        private SchoolContext context = new SchoolContext();
        private GenericRepository<Department> departmentRepository;
        private GenericRepository<Course> courseRepository;
    
        public GenericRepository<Department> DepartmentRepository
        {
            get
            {
    
                if (this.departmentRepository == null)
                {
                    this.departmentRepository = new GenericRepository<Department>(context);
                }
                return departmentRepository;
            }
        }
    

    你的工作单元持有上下文,如果它需要引用一个存储库,如果它没有被创建,它会创建它,并传入它持有的上下文。

    本文还介绍了他们如何将常规 MVC 控制器实现转换为使用工作单元模式。

    【讨论】:

    • 好文章!感谢您的链接。
    • 糟糕的文章!他们确实在 unitofwork 类中创建上下文和存储库,而不是使用 di 工具注入两者。
    【解决方案3】:

    在这个post 中说你必须在你的存储库基础中实现 IUnitOfWork 接口。

    我希望这会有所帮助。 问候

    【讨论】:

      【解决方案4】:

      Unit of Work
      Repository

      UnitOfWork 用于管理原子操作。

      Repository 封装了持久化在数据存储中的一组对象以及对它们执行的操作。

      如果您传递上下文或 UnitOfWork,那么您没有实现 UnitOfWork+Repository 模式,导致您从 UnitOfWork 中退出它的责任。也就是你不需要它。

      如果您只通过 DbSet,则正确实现。其实你不需要更多。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-02-02
        • 2011-06-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多