3

近一年後,我開始一個新的mvc項目,這次是版本4.我想知道以下存儲庫模式的實現是否比優點更多的缺點。存儲庫模式+工作單元

public interface IRepository<T> where T : class 
{ 
    IEnumerable<T> GetAll(); 

    IQueryable<T> Query(Expression<Func<T, bool>> filter); 

    void Add(T entity); 

    void Remove(T entity); 
} 

public interface IUnitOfWork 
{ 
    void Commit(); 
} 

public interface IDbContext : IDisposable 
{ 
    IDbSet<T> Set<T>() where T : class; 

    int SaveChanges(); 
} 

public class DbContextAdapter : IDbContext 
{ 
    private readonly DbContext _myRealContext; 

    public DbContextAdapter() 
    { 
     this._myRealContext = new EstafaContext(); 
    } 

    public void Dispose() 
    { 
     _myRealContext.Dispose(); 
    } 

    public IDbSet<T> Set<T>() where T : class 
    { 
     return _myRealContext.Set<T>(); 
    } 

    public int SaveChanges() 
    { 
     return _myRealContext.SaveChanges(); 
    } 
} 

public class SqlRepository<T> : IRepository<T> where T : class 
{ 
    private IDbSet<T> _dbSet; 

    public SqlRepository(IDbContext dbContext) 
    { 
     this._dbSet = dbContext.Set<T>(); 
    } 

    public IEnumerable<T> GetAll() 
    { 
     return this._dbSet.ToList(); 
    } 

    public IQueryable<T> Query(Expression<Func<T, bool>> filter) 
    { 
     return this._dbSet.Where(filter); 
    } 

    public void Add(T entity) 
    { 
     this._dbSet.Add(entity); 
    } 

    public void Remove(T entity) 
    { 
     this._dbSet.Remove(entity); 
    } 
} 

public class SqlUnitOfWork : IDisposable, IUnitOfWork 
{ 
    private IDbContext _dbContext; 

    private SqlRepository<Cliente> _clientes ; 

    public SqlUnitOfWork() 
    { 
     this._dbContext = new DbContextAdapter(); 
    } 

    public void Dispose() 
    { 
     if (this._dbContext != null) 
     { 
      this._dbContext.Dispose(); 
     } 
     GC.SuppressFinalize(this); 
    } 

    public IRepository<Cliente> Clientes 
    { 
     get { return _clientes ?? (_clientes = new SqlRepository<Cliente>(_dbContext)); } 
    }  

    public void Commit() 
    { 
     this._dbContext.SaveChanges(); 
    } 
} 

這樣我就可以通過SqlUnitOfWork從單一點管理所有存儲庫。 我在之前的項目中使用過這種設計,效果很好,但我覺得效率不高,也許是多餘的。 值得添加這樣一個抽象層嗎?

在此先感謝!

+0

[實現存儲庫,返回從EF實體映射的域模型]的可能副本(http://stackoverflow.com/questions/13387858/implementing-a-repositoryt-that-returns-a-domain-model -def-from-ef-entit) – jgauffin

+0

你也可以在這裏閱讀我的答案:http://stackoverflow.com/questions/10190384/repository-pattern-implementation/10190432#10190432 – jgauffin

回答

1

雖然我的實現並不完全像你一樣,但對我來說似乎非常穩固。

其他唯一的變化我通常做的是定義特定的接口爲每個實體類型庫中,像這樣:

public interface IClienteRepository : IRepository<Cliente> 
{ 
    IEnumerable<Cliente> GetByName(string firstName); 
    // etc 
} 

這樣,我仍然可以使用所有存儲庫統稱爲我的CRUD操作,但我也可以使用同一個存儲庫來抽象出一些查詢邏輯。您的存儲庫的用戶應該只需知道他們想要什麼,而不知道如何獲取它。

這當然有點乏味,需要你製作具體的存儲庫實現來增加額外的功能,但它只是封裝了你在應用程序中任何地方都有的查詢邏輯。

+0

thx @armen,我看到你的觀點。所以,無論何時我需要一些數據對象的縮減集合,最好是有一個特定的類型庫實現。 – n3k

1

我不知道它是否有更多的缺點或優點,但多年來,我發現這種類型的存儲庫模式越來越少用。除非動態地切換數據庫或數據源是一種真正的可能性,否則如果您需要一些瘋狂的模擬宇宙測試覆蓋率,我認爲它比它的價值更麻煩。

只是我的個人喜好,但我喜歡我的數據訪問方法更明確一點。例如,如果我將模型返回到視圖,他們肯定會看起來不同於我的數據庫中的表。所以我想要一個GetAllModelX方法,而不是GetAllDbTableRows方法。

那麼這個轉換代碼要放在哪裏?在控制器中?另一個將實體轉換爲模型的數據訪問層?有沒有對錯的答案?可能不會。

我絕對在這裏扮演魔鬼的擁護者,但以我的經驗,我已經擺脫了這個通用的存儲庫設計,轉而使用返回/接受模型的數據訪問層,並處理所有的查詢/ CRUDding/UnitOfWork通常使用EF來針對數據庫。但是,再次,我是一個經典的單元測試人員,他不會做太多的嘲諷,並且會進行更多的集成測試。

+0

雖然我同意儘可能多地將工作小鎮推向「層級」,但是「服務」層不是與您的存儲庫/實體進行交互以及構建域級模型的理想場所嗎?當然是 –

+0

。但是如果你所有的版本庫都保存了一個客戶端而不必顯式編寫'SaveChanges()'你真的在做什麼?寫100行代碼,以免你寫20行後?我發現你經常會遇到這樣的存儲庫,因爲它打破了「工作單元」這個名稱的靈活性 – Didaxis

+0

我還應該指出,我通常處理大型事務,而我的數據訪問操作從來沒有像簡單的做法是直接添加/更新數據庫。所以顯然這樣一個簡單的存儲庫對像我這樣的人沒有什麼好處。這種類型的設計絕對有案例,但即使在簡單的網站場景中,我發現它通常是過度殺傷 – Didaxis

相關問題