2017-09-07 3 views
1

私はいくつかの計算に進むことができる式ツリーのいくつかのプロパティの値を読んでみたいと思います。式ツリーでプロパティの値を読み取る方法は?

var products = db.Products 
    .Where(GetPredicate()) 
    .ToList(); 

private Expression<Func<Product, bool>> GetPredicate() 
{ 
    ParameterExpression pe = Expression.Parameter(typeof(Product), "p"); 
    Expression exp0 = Expression.Property(pe, "Price"); 

    //I'd like to know the value of the 'Price' 
    // so I can do some calculation, then check whether 
    //this particular product meet the criteria... 

    Expression body = Expression.Constant(Result); //result is a boolean 
    var expr = Expression.Lambda<Func<Product, bool>>(body, new ParameterExpression[] { pe }); 
     return expr; 

} 
+1

Expression.Convertを使用しようとしましたか? – napi15

+0

[式ツリーを使用したオブジェクトのプロパティの読み込み]の可能な複製(https://stackoverflow.com/questions/16436323/reading-properties-of-an-object-with-expression-trees) – johnnyRose

+1

式ツリーを作成するとき'GetPredicate'には' Price'という値はありません( 'Product'オブジェクトがないので)。したがって、コンパイルされた式ツリーに渡す前に、実際の価値を調べることはできません。しかし、必要に応じて式ツリーに何らかの種類の比較や制約を追加することができます。何かは次のようになります: 'Expression.Add(exp0、Expression.Constant(156));'戻り値などをチェックできます。しかし、値はまだ分かりません。入力値が比較されることを知っているだけです私は何かを見逃したり、あなたの質問を理解していませんでしたか? –

答えて

0

あなたは式がクエリによって理解されていることを確認する必要があなたの問題を解決するために式を使用しようとする前に、データベースクエリプロバイダ(LINQ2SQL、EFなど)

を使用しているように見えますプロバイダ。あなたのケースでは、多くのMathメソッドをT-SQLの有効なステートメントに変換することができます。また、Entity Frameworkを使用している場合は、System.Data.Objects.SqlClient.SqlFunctionsクラスを利用して式を作成し、ネイティブなT-SQL関数に対してSQL Server側でロジックを実行することもできます。

、式ツリーに理解するための何かが、これは一度あなたがそれを呼び出すコンパイルLambdaExpression、でない限り、値は、式を構築するから得ることができないことである、あなたのケースでは、あなたはbool値を取得することができます。

あなたは価格値で作業する必要がある場合は、式がMathクラスの静的Sqrtメソッドを呼び出して、あなたの例では、他のロジックへの呼び出しを表す複数の式を作成する必要があります。あなたはすべてのロジックを見ることができるように

private Expression<Func<Product, bool>> GetPredicate() 
{ 
    var pe = Expression.Parameter(typeof(Product), "p"); 
    var price = Expression.Property(pe, "Price"); 
    var priceDouble = Expression.Convert(price, typeof(double)); 
    var sqrtMethod = typeof(Math).GetMethod("Sqrt"); 
    var sqrtCall = Expression.Call(sqrtMethod, priceDouble); 
    var constant = Expression.Constant(4d); 
    var gtThan = Expression.GreaterThan(sqrtCall, constant); 

    var lambda = Expression.Lambda<Func<Product, bool>>(gtThan, pe); 
    return lambda; 
} 

表現であるとプロバイダが式全体を消費し、ターゲットプロセスが理解できる構文に変換することができます。以前の式が生成されますp => Math.Sqrt((double)p.Price) > 4d

関連する問題