2012-08-28 43 views
5

我正在使用EF /知识库/工作单元,但我很难理解一些细节。在UnitOfWork内部,我创建了一个新的EF DbContext(EmmaContext),但是看看版本库里面的内容,我知道它是错误的,我如何正确地获取回购库中的上下文?也许我完全走错路了?实体框架和工作单元

这里是我的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 
} 

这里是仓库:

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

回答

4

山姆:我通常觉得舒服的具体信息库中的构造函数采取具体的UnitOfWork:

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

存储库和UOW通常协同工作,需要知道对方一点点。

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

+0

这基本上是我所做的,增加了一个IUnitOfWork接口,但是就单元测试而言,你认为怎么样?你真的要单元测试你的仓库和工作单元吗? – Sam

+0

想了一下之后,我想知道如何将实现抽象为调用代码,并仍然将上下文从IoC容器获取到回购中?你有代码示例吗?谢谢!顺便说一句 - 我刚读了你的MVC 3.0书,这本好书! – Sam

+0

@Sam - 谢谢:) – OdeToCode

1

在这种说,你必须实现在你的仓库基地IUnitOfWork接口。

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

4

这是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控制器实现转换为使用工作单元模式。

+0

伟大的文章!感谢您的链接。 –

+7

不好的文章!他们在unitofwork类中创建上下文和存储库,而不是使用di工具注入。 – Elisabeth

0

Unit of Work
Repository

的UnitOfWork是用于管理原子操作。

存储库封装了保存在数据存储中的一组对象以及通过它们执行的操作。

如果您通过上下文或UnitOfWork,而不是实现UnitOfWork + Repository模式,则会导致您从UnitOfWork中撤出其职责。也就是你不需要它。

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