0

新しいasp.netWebプロジェクトを開始する準備をしており、LINQ-to-SQLを使用します。インターフェースとジェネリックを使用してデータベース内の各テーブルのリポジトリを作成するMikeHadlowが見つけた情報を使用して、データレイヤーのセットアップを取得するために少し作業を行いました。最初はこれが面白いアプローチだと思いました。ただし、今では、基本リポジトリクラスを作成し、それを継承して、アクセスする必要のあるテーブルのTableNameRepositoryクラスを作成する方が理にかなっていると思います。

クリーンでテスト可能な方法でテーブルに固有の機能を追加できるのはどのアプローチですか?これが参考のために私のリポジトリの実装です。

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

2 に答える 2

5

すべてのテーブルにリポジトリを作成するべきではありません。
代わりに、ドメインモデルに存在するすべての「エンティティルート」(または集約ルート)のリポジトリを作成する必要があります。パターンの詳細と実際の例をここで確認できます。

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

于 2011-02-08T13:23:53.573 に答える
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のようなものが役立つかもしれないので注意してください。

于 2008-09-19T16:55:01.437 に答える