2017-09-07 3 views
1

Ich möchte den Wert einiger der Eigenschaften im Ausdrucksbaum lesen, einige kann ich mit einigen Berechnungen fortfahren.Wie liest man die Werte einer Eigenschaft in der Ausdrucksbaumstruktur?

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

Haben Sie versucht, die Expression.Convert zu verwenden? – napi15

+0

Mögliches Duplikat von [Eigenschaften eines Objekts mit Ausdrucksbäumen lesen] (https://stackoverflow.com/questions/16436323/reading-properties-of-an-object-with-expression-trees) – johnnyRose

+1

Wenn Sie einen Ausdrucksbaum erstellen In GetPredicate haben Sie keinen Wert von 'Price' (weil Sie kein' Product' Objekt haben). Sie können also keinen echten Wert abrufen, bevor Sie ihn an den kompilierten Ausdrucksbaum übergeben. Aber Sie können dem Ausdrucksbaum eine Art von Vergleichen und Einschränkungen hinzufügen, wie Sie wollen. Etwas sieht so aus: 'Expression.Add (exp0, Expression.Constant (156));' Dann kannst du den zurückgegebenen Wert usw. überprüfen. Aber du weißt noch keinen Wert, du weißt nur, dass dein Eingabewert verglichen wird und etc. Hab ich etwas verpasst oder deine Frage nicht verstanden? –

Antwort

0

Sie scheinen eine Datenbankabfrage-Provider werden (LINQ2SQL, EF, etc.)

Bevor Sie versuchen, Ausdrücke zu verwenden, um Ihr Problem, das Sie den Ausdruck sicherstellen müssen, lösen, indem die Abfrage verstanden wird Anbieter. In Ihrem Fall können viele der Math Methoden in gültige T-SQL-Anweisungen konvertiert werden. Wenn Sie Entity Framework verwenden, möchten Sie möglicherweise die Klasse System.Data.Objects.SqlClient.SqlFunctions nutzen, um einen Ausdruck zu erstellen und Ihre Logik auf der SQL Server-Seite gegen native T-SQL-Funktionen auszuführen.

Jetzt, etwas auf die Expression Bäume zu verstehen ist, dass die Werte nicht aus der Konstruktion Ausdrücke erhalten werden, wenn dies ein LambdaExpression ist, einmal kompiliert Sie es aufrufen, in Ihrem Fall können Sie den bool Wert erhalten. Wenn Sie mit dem Preiswert arbeiten müssen, müssen Sie weitere Ausdrücke erstellen, die den Aufruf der anderen Logik darstellen, in Ihrem Beispiel die Ausdrücke, die die statische Methode Sqrt der Klasse Math aufrufen.

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; 
} 

Wie Sie alle die Logik sehen kann, ist ein Ausdruck und der Anbieter kann den gesamten Ausdruck verbrauchen und es Syntax konvertieren, die durch den Zielprozess verstanden werden kann. Der vorherige Ausdruck generiert p => Math.Sqrt((double)p.Price) > 4d

Verwandte Themen