Greifen Sie auf den Wert eines Mitgliedsausdrucks zu

c# expression-trees lambda linq

Frage

Wenn ich ein Produkt habe.

var p = new Product { Price = 30 };

und ich habe die folgende linq Abfrage.

var p = new Product { Price = 30 };

In einem IQueryable-Provider erhalte ich eine MemberExpression für den p.Price, der einen Constant Expression enthält, aber ich kann den Wert "30" nicht zurückbekommen.

Update Ich habe es versucht, aber es scheint nicht zu funktionieren.

var p = new Product { Price = 30 };

Prost.

Akzeptierte Antwort

Sie können einen Lambda-Ausdruck kompilieren und aufrufen, dessen Body der Member-Zugriff ist:

private object GetValue(MemberExpression member)
{
    var objectMember = Expression.Convert(member, typeof(object));

    var getterLambda = Expression.Lambda<Func<object>>(objectMember);

    var getter = getterLambda.Compile();

    return getter();
}

Die lokale Auswertung ist eine gängige Technik beim Analysieren von Ausdrucksbäumen. LINQ to SQL macht genau das an einigen Stellen.


Expertenantwort

Der konstante Ausdruck verweist auf eine vom Compiler generierte Capture-Klasse. Ich habe die Entscheidungspunkte usw. nicht aufgenommen, aber hier ist, wie man 30 davon bekommt:

var p = new Product { Price = 30 };
Expression<Func<Product, bool>> predicate = x => x.Price == p.Price;
BinaryExpression eq = (BinaryExpression)predicate.Body;
MemberExpression productToPrice = (MemberExpression)eq.Right;
MemberExpression captureToProduct = (MemberExpression)productToPrice.Expression;
ConstantExpression captureConst = (ConstantExpression)captureToProduct.Expression;
object product = ((FieldInfo)captureToProduct.Member).GetValue(captureConst.Value);
object price = ((PropertyInfo)productToPrice.Member).GetValue(product, null);

price ist jetzt 30 . Beachten Sie, dass ich annahm, dass Price eine Eigenschaft ist, aber in Wirklichkeit würden Sie eine GetValue Methode schreiben, die die Eigenschaft / das Feld behandelt.




Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum