2011-08-05 12 views
7

私は結論(多くの試行の後に)リポジトリ&の作業単位は、エンティティフレームワークを使用しているときに間違っている、間違って、間違っているとよく聞きましたthis says whyかなり。リポジトリなしでEntity Frameworkでの再利用可能なクエリ。どうやって?

しかし、私は本当にそれらの埋め込みクエリが嫌いです。問題は、私がリポジトリなどと対立している場合はどこに置くことができますか? (クリーンな回答のみお願いします。

私のリポジトリと作業単位とインタフェースを含む2つのプロジェクトは、,のファイルで埋められませんでした。私は多くの人が自分自身を含めて、リポジトリのバンドワゴンに飛び乗っただけだと思います。それはほかの人たちがやっていることだからですが、振り返ってみると、どこにも行けないのです。

/

リチャードあなたがそれらを置くことを期待します

答えて

3

ため息?

  1. 再利用可能な部品を定義するために、彼らがどこにいる彼らは、とすると、カスタム拡張メソッド、query views、マッピングされたデータベースビューまたはカスタムdefining queriesを使用
  2. いくつかの別のクラスのメソッドとしてすべての単一のクエリを公開:あなただけのいくつかの選択肢を持っています。メソッドはIQueryableを公開してはならず、パラメータとして= Expressionを受け入れることはできません。メソッド全体では、クエリロジックをラップする必要があります。しかし、これはあなたのクラスを関連するメソッドをリポジトリ(擬似または偽装することができる唯一のもの)に似ています。この実装は、ストアドプロシージャで使用される実装に近いです。
  3. これまでの方法と同じことを行いますが、クエリを別のクラスに配置する代わりに、静的メソッドとしてエンティティに直接配置します。これは、静的メソッドをmocking(それはより複雑なテストフレームワークを必要とする)に置き換えることができないため、テスト可能です。これはactive record patternの一部であり、各エンティティはデータベースへのロードと保存を担当します。

カスタム拡張方法の例:メソッドを公開するカスタムクラスの

public static IQueryable<TEntity> GetByName(this IQueryalbe<TEntity> query, string name) 
    where TEntity : IEntityWithName 
{ 
    return query.Where(e => e.Name == name); 
} 

例:

public class QueryProvider 
{ 
    public QueryProvider() {} 

    public IEnumerable<TEntity> GetByName(IYourContext context, string name) 
     where TEntity : IEntityWithName 
    { 
     return context.CreateObjectSet<TEntity>().Where(e => e.Name == name).ToList(); 
    } 
} 
+0

エンティティフレームワークとテストは、私の見解ではほぼ矛盾していますが、あなたが意味するものは分かります。物事が複雑になるとすぐに、上記のアプローチは崩壊しますが、あなたの言うように、そこにはほかに何がありますか?リポジトリにすべてをラップするだけで、その責任はどこかに移ります。 – Richard

2

Build Reusable, Testable Queries Part 1

これは、私は、再利用可能なクエリの構築について書いたブログ記事です。拡張メソッドを使用すると、合成可能なクエリを構築できます。

仕様パターンのようなパターンを使用すると、再利用または保存(シリアル化)できるクエリを作成するのに役立ちます。さらに、ダブルエントリシステムを使用すると、2つの異なるデータベースで同じクエリインスタンスを実行できます。

次の例では、EFを使用せずにIEnumerableをEFコンテキストに置き換えて、あなたが探しているものを取得します。パラメータはコンストラクタを介して渡されます。

public class PartialMatchQuery : IModelQuery<string, IEnumerable<string>> 
{ 
    private readonly string partial; 

    public PartialMatchQuery(string partialString) 
    { 
     partial = partialString; 
    } 

    public IEnumerable<string> Execute(IEnumerable<string> model) 
    { 
     return model.Where(s => s.ToLower().Contains(partial)); 
    } 
} 
関連する問題