2013-03-12 13 views
7

System.Linq.Expressions.Expressionクラスを使用して動的にSQL「WHERE」節を作成しています。シンプルな節ではうまくいきます。 「PhaseCode = X」句を追加するために、私は次のようにします。LINQクエリ用の式ツリーを使用してIQueryable.Anyを構築します。

var equalTarget = Expression.Constant(phaseCode, typeof(int?)); 
var phaseEquals = Expression.Equal(Expression.PropertyOrField(projParam, "PhaseCode"), equalTarget); 

しかし、今私は、プロジェクトが特定のグループに割り当てられている場合、レコードを返します表現を構築しようとしています。プロジェクトとグループには多対多の関係があります。 次のように式ツリーがなければ、私はそれを行うだろう:

db.Projects.Where(p => .... && p.GroupsAssigned.Any(g => g.ID == groupId)) 

しかし、私はExpressionクラスを持つことを表現する方法を見つけるように見えることはできません。 は私が把握することはできません二つのこと、実際にあります。

  • x.Anyを(行うためにどのようにテーブル
  • 間の関係をトラバースする方法)

は、すべてのヘルプは大歓迎です。

答えて

10

Enumerable.AnyまたはQueryable.Anyのような拡張メソッドを呼び出すことは、シーケンスと、WHERE句のために作成したラムダ式の静的メソッド呼び出しです。これはあなたがを介してこれを行うことができませんことを奇妙に思えるが、

static Expression BuildAny<TSource>(Expression<Func<TSource, bool>> predicate) 
{ 
    var overload = typeof(Queryable).GetMethods("Any") 
           .Single(mi => mi.GetParameters().Count() == 2); 
    var call = Expression.Call(
     overload, 
     Expression.PropertyOrField(projParam, "GroupsAssigned"), 
     predicate); 

    return call; 
} 

Queryable.Any<T>について、あなたはメソッドにこれをロールアップする必要があります

// for Enumerable.Any<T>(IEnumerable<T>,Predicate<T>) 
var overload = typeof(Enumerable).GetMethods("Any") 
           .Single(mi => mi.GetParameters().Count() == 2); 
var call = Expression.Call(
    overload, 
    Expression.PropertyOrField(projParam, "GroupsAssigned"), 
    anyLambda);  

:あなたはこれを行うにはExpression.Callを使用することができます通常のクエリです。

+0

解決に感謝します。 Expression.Call()は私が必要としていたものです。あなたの質問に答えるために、私はコンパイル時にWHEREステートメント内のいくつのAND部分があるかわからないので、この場合は通常のクエリを実行できません。それはすべてユーザーが検索フォームで選択した内容に依存します。式ツリーを構築することが唯一の有効な解決策であるようです。 –

+0

ありがとうございました。私はこれを見て間違いました。私は間違っていました。 'typeof(Queryable).GetMethods(" Any ")。 : 'typeof(Enumerable).GetMethods(" Any ")。シングル(mi => mi.GetParameters()。Count()== 2);' –

関連する問題