2012-08-28 44 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。其實你不需要更多。