2008-09-19 55 views
0

我正準備開始一個新的asp.net web項目,並且我要去LINQ到SQL。我已經完成了一些工作,使用我在Mike Hadlow中發現的一些信息來獲取數據層設置,這些信息使用Interface和泛型爲數據庫中的每個表創建一個Repository。起初我認爲這是一個有趣的方法。然而,現在我認爲創建一個基本Repository類並從它繼承來爲我需要訪問的表創建一個TableNameRepository類會更有意義。版本庫模式實施經驗

哪種方法將允許我以清潔可測試的方式添加特定於表格的功能?這是我的Repository實現供參考。

public class Repository<T> : IRepository<T> where T : class, new() 
{ 
    protected IDataConnection _dcnf; 

    public Repository() 
    { 
     _dcnf = new DataConnectionFactory() as IDataConnection; 
    } 

    // Constructor injection for dependency on DataContext 
    // to actually connect to a database 
    public Repository(IDataConnection dc) 
    { 
     _dcnf = dc; 
    } 

    /// <summary> 
    /// Return all instances of type T. 
    /// </summary> 
    /// <returns>IEnumerable<T></returns> 
    public virtual IEnumerable<T> GetAll() 
    { 
     return GetTable; 
    } 

    public virtual T GetById(int id) 
    { 
     var itemParam = Expression.Parameter(typeof(T), "item"); 
     var whereExp = Expression.Lambda<Func<T, bool>> 
      (
       Expression.Equal(
        Expression.Property(itemParam, PrimaryKeyName), 
        Expression.Constant(id) 
       ), new ParameterExpression[] { itemParam } 
      ); 
     return _dcnf.Context.GetTable<T>().Where(whereExp).Single(); 
    } 

    /// <summary> 
    /// Return all instances of type T that match the expression exp. 
    /// </summary> 
    /// <param name="exp"></param> 
    /// <returns>IEnumerable<T></returns> 
    public virtual IEnumerable<T> FindByExp(Func<T, bool> exp) 
    { 
     return GetTable.Where<T>(exp); 
    } 

    /// <summary>See IRepository.</summary> 
    /// <param name="exp"></param><returns></returns> 
    public virtual T Single(Func<T, bool> exp) 
    { 
     return GetTable.Single(exp); 
    } 

    /// <summary>See IRepository.</summary> 
    /// <param name="entity"></param> 
    public virtual void MarkForDeletion(T entity) 
    { 
     _dcnf.Context.GetTable<T>().DeleteOnSubmit(entity); 
    } 

    /// <summary> 
    /// Create a new instance of type T. 
    /// </summary> 
    /// <returns>T</returns> 
    public virtual T Create() 
    { 
     //T entity = Activator.CreateInstance<T>(); 
     T entity = new T(); 
     GetTable.InsertOnSubmit(entity); 
     return entity; 
    } 

    /// <summary>See IRepository.</summary> 
    public virtual void SaveAll() 
    { 
     _dcnf.SaveAll(); 
    } 

    #region Properties 
    private string PrimaryKeyName 
    { 
     get { return TableMetadata.RowType.IdentityMembers[0].Name; } 
    } 

    private System.Data.Linq.Table<T> GetTable 
    { 
     get { return _dcnf.Context.GetTable<T>(); } 
    } 

    private System.Data.Linq.Mapping.MetaTable TableMetadata 
    { 
     get { return _dcnf.Context.Mapping.GetTable(typeof(T)); } 
    } 

    private System.Data.Linq.Mapping.MetaType ClassMetadata 
    { 
     get { return _dcnf.Context.Mapping.GetMetaType(typeof(T)); } 
    } 
    #endregion 
} 
+0

你是不是問一個具體問題。 – ddaa 2008-09-19 14:24:30

回答

1

我會忍不住表明您是否使用的具體類型或不應該沒關係,因爲如果你的使用依賴注入(城堡?)來創建存儲庫(這樣你就可以用不同的緩存將它們包裝等等),那麼你的代碼庫不會更聰明,無論你做了什麼。

然後,只要問你的DI存儲庫。例如。對於城堡:

public class Home { 
    public static IRepository<T> For<T> { 
    get { 
     return Container.Resolve<IRepository<T>>(); 
    } 
    } 
} 

就我個人而言,直到你找到需要的時候,

我想你的問題的另一半是你是否可以輕鬆地提供內存實現的IRepository進行測試和緩存的目的。爲此,我會留意,因爲linq-to-objects可能會很慢,您可能會發現像http://www.codeplex.com/i4o這樣有用的東西。

5

您不應該爲每個表創建存儲庫。
相反,您應該爲您的域模型中存在的每個「實體根」(或聚合根)創建一個存儲庫。您可以瞭解更多的模式,在這裏看到一個工作例子:

http://deviq.com/repository-pattern/