2011-11-08 5 views
0

アトミックコンテキストを持つC#リポジトリを作成しようとしていますが、閉鎖の使用には完璧な状況だと感じていますが、 C#。私は、リポジトリ内の主な方法としてこれを持っている:閉鎖メソッドとしての動的LINQクエリの作成

... 
    protected virtual IQueryable<T> AsQueryable() 
    { 
     return _context.ObjectSet<T>().AsQueryable(); 
    } 
... 

。一方、私のようなメソッドを持つクラスを派生しています

... 
    public IQueryable<Arc> ByRun(Run run) 
    { 
     IQueryable<Arc> query = from o in AsQueryable() 
            from r in o.Runs 
            where r.Id == run.Id 
            select o; 
     return query; 
    } 
... 

と私はIEnumerableをを返すために、私のクエリ方法を変更すると、すぐに処分したいです

... 
    protected virtual IEnumerable<T> AsEnumerable() 
    { 
     using (IContextUnitOfWork unitOfWork = new EFUnitOfWork()) 
     { 
      return unitOfWork.ObjectSet<T>().ToList(); 
     } 
    } 
... 

問題、当然のことながら、文脈が配置されると、結果のIEnumerableをセットにLINQを呼び出すと失敗することです:文脈で、これは(のようなもの)を使用します。したがって、私はByRun()メソッドをバンドルして、それをクロージャとして使用するAsEnumerable()に渡すべきだと考えました。

私の元の言語スタイルではありませんが、私はRubyでクロージャーを学びました。 AsEnumerableメソッドは、コンテキストを開く渡された操作を実行し、戻ってくる

ByRun(Run run) 
    AsEnumerable do |query| 
    from o in query 
      from r in o.Runs 
      where r.Id == run.Id 
      select o; 
    end 
end 

:そこに、私がやろうとしていることは、この混同擬似コードのようになります。私は構文を理解するとこれを行うことができると確信しているので、私はこのように実装したいAsEnumerableメソッドとByRunメソッドを探しています。

+0

、私はLINQとクロージャを使用して実装されたIQueryableインターフェイスには多くの方法が、私はちょうどにコードを取得することができないことを実現します例を参照してください。 – JohnMetta

答えて

1

私が質問を正しく理解している場合は、最後にAsEnumerableが呼び出され、コンテキストがクエリの直後に配置されるようにするために、任意のクエリにラッパーを付けたいですか?

もしそうなら、このしようと、(あなたのベースクラスは、Tパラメータを持つジェネリックであると仮定):ここAsEnumerableのパラメータが含まラムダ式である

public IEnumerable<Arc> ByRun(Run run) 
{ 
    return AsEnumerable(query => from o in query 
           from r in o.Runs 
           where r.Id == run.Id 
           select o); 
} 

protected virtual IEnumerable<T> AsEnumerable(Func<ObjectSet<T>, IQueryable<T>> query) 
{ 
    using (IContextUnitOfWork unitOfWork = new EFUnitOfWork()) 
    { 
     return query(unitOfWork.ObjectSet<T>()).AsEnumerable(); 
    } 
} 

と使用例を唯一のパラメータとしてObjectSet<T>をとり、IQueryable<T>を返すデリゲート。だから、派生クラスで次のコードを持っている論理的に等価です:補遺として

public IEnumerable<Arc> ByRun(Run run) 
{ 
    using (IContextUnitOfWork unitOfWork = new EFUnitOfWork()) 
    { 
     return (from o in unitOfWork.ObjectSet<T>() 
       from r in o.Runs 
       where r.Id == run.Id 
       select o).AsEnumerable(); 
    } 
} 
+0

これを忘れてしまった。ありがとう、@A – JohnMetta