2010-12-28 15 views
2

ここでは、Calling a Method from an ExpressionMSDNの例をいくつか見てきましたが、以下のクエリのAny()に対して適切なメソッド呼び出し/オブジェクト型を取得できませんでした。私は、プロパティの呼び出しを取得することができるようですが、子プロパティのIEnumerable部分は取得できません。
billing_map_set_luはbillmaps_luの親であり、Entity Frameworkの関連付けとして定義されています。式ツリーを使用してEntity Frameworkで.Any拡張メソッドを呼び出す

私が式ツリーを使用しているのは 実行時に1-n .SelectMany(p => p.billmaps_lu).Where(predicate)節でクエリを定義できるようにする必要があります。だから私は表現木を作ることができたら、私はこのシステムのためにたくさんあるさまざまな組み合わせをすべて扱うことができると考えました。

var myResults = ctx.billing_map_set_lu 
        .Where(p => p.billmaps_lu.Any(b => b.billmap_columnname == "templatesittings_key" && b.billmap_columnvalue == 428264)) 
            SelectMany(p => p.billmaps_lu) 
        .Where (b =>b.billmap_columnname =="locations_key" && b.billmap_columnvalue == 12445) 
            Select(z => z.billing_map_set_lu); 

私は上記の部分が細かいようだが、私は.ANYをしようとするとき、私はできないみたいです上記のサンプルを使用してかなりの数の試み...

ParameterExpression bms = Expression.Parameter(typeof(billmaps_lu)); 
Expression left1 = Expression.Property(bms, typeof(billmaps_lu).GetProperty("billmap_columnname")); 
Expression right1 = Expression.Constant("templatesittings_key", typeof(string)); 
Expression InsideAny1 = Expression.Equal(left1, right1); 
Expression left2 = Expression.Property(bms, typeof(billmaps_lu).GetProperty("billmap_columnvalue")); 
Expression right2 = Expression.Constant(428264, typeof(int)); 
Expression InsideAny2 = Expression.Equal(left2, right2); 
Expression myWhereClause1 = Expression.AndAlso(InsideAny1, InsideAny2); 

を試してみました適切なオブジェクトを取得するための適切なプロパティ/メソッドを取得します。 (私は間違ったユニットで作業している物理学の問題のように感じます)私はそれが私が行方不明であることを望んでいます、私はかなりExpression Treesを使い慣れていません。私の頭がどこにあるのか、誰かが私を正しい方向に向けることができるかを示す。

MethodInfo method = typeof(Enumerable).GetMethods().Where(m => m.Name == "Any" && m.GetParameters().Length == 2).Single().MakeGenericMethod(typeof(billing_map_set_lu).GetProperty("billmaps_lu").PropertyType); 
ParameterExpression billMapSetParameter = Expression.Parameter(typeof(billing_map_set_lu), "p"); 
ParameterExpression billMaps = Expression.Parameter(typeof(billmaps_lu), "p1"); 
var myFunction = Expression.Lambda<Func<billmaps_lu, bool>>(Expression.Call(method, Expression.Property(billMapSetParameter, typeof(billing_map_set_lu).GetProperty("billmaps_lu")), myWhereClause1), billMaps) 

答えて

0

免責事項、私はコンパイルされた作業コードを持っていません。

2つの問題があります。

あなたが必要なパラメータではありません
ParameterExpression billMapSetParameter = Expression.Parameter(typeof(billing_map_set_lu), "p"); 

Expression.Lambda<Func<billmaps_lu, bool>>(Expression.Call(method, Expression.Property(**billMapSetParameter**, typeof(billing_map_set_lu).GetProperty("billmaps_lu")), myWhereClause1), billMaps) 

変更billMaps ParamterExpressionにbillMapSetParameterは、その後、あなたが行くことが良いことがあり

最初の問題は、おそらくです。 PropertyExpressionを呼び出して、ParameterExpressionからbillMapSetを取得します。

第2の問題:わかりませんが、私の腸の感覚 Where句を式< .Func < >>のタイプのConstantExpressionとして渡す必要があるかもしれません。いずれのメソッドも2つのパラメータをとります。そのうちの2つ目は式< .Func < >>です(またはFunc <?は覚えていません)。

var whereExpression = Expression.Lambda<.Func<.billmaps_lu, bool>>(myWhereClause1, bms); 
var ce = Expression.Constant(whereExpression) 

"myWhereClause1"の元の場所にバック・セクションを渡します。

クロス指は

編集 - スクラップこと、SHOW MI ZEH CODEZ

public class Foo 
{ 
    public List<string> Strings { get; set; } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     Func<Foo, bool> func = 
      a => a.Strings.Any(b => b == "asdf"); 

     // b => b == "asdf"; 
     var bParameter = Expression.Parameter(typeof (string)); 
     var asdfConstant = Expression.Constant("asdf"); 
     var compare = Expression.Equal(bParameter, asdfConstant); 
     var compareExpression = Expression.Lambda<Func<string, bool>>(compare, bParameter); 
     var ceCompareExpression = Expression.Constant(compareExpression.Compile()); 

     // a => a.Strings.Any(compareExpression) 
     var parameter = Expression.Parameter(typeof (Foo)); 

     var foosProperty = Expression.Property(parameter, typeof (Foo).GetProperty("Strings")); 
     MethodInfo method = typeof(Enumerable).GetMethods().Where(m => m.Name == "Any" && m.GetParameters().Length == 2).Single().MakeGenericMethod(typeof(string)); 

     var anyMethod = Expression.Call(method, foosProperty, ceCompareExpression); 

     var lambdaExpression = Expression.Lambda<Func<Foo, bool>>(anyMethod, parameter); 

     // Test. 
     var foo = new Foo {Strings = new List<string> {"asdf", "fdsas"}}; 

     Console.WriteLine(string.Format("original func result: {0}", func(foo))); 
     Console.Write(string.Format("constructed func result: {0}", lambdaExpression.Compile()(foo))); 

     Console.ReadKey(); 
    } 
} 
+0

を作品スミス@Sleeperありがとうございます!私はかなりこれをあきらめて、表現木を使用しないで回避しましたが、コードをリファクタリングするときにあなたの答えを試していきます。再度、感謝します! – RCrabtree

関連する問題