Accéder à la valeur d'une expression de membre
Si j'ai un produit.
var p = new Product { Price = 30 };
et j'ai la suite d'une requête linq.
var q = repo.Products().Where(x=>x.Price == p.Price).ToList()
Dans un IQueryable fournisseur, je reçois un MemberExpression de retour pour les p.Prix qui contient une Expression Constante, cependant je n'arrive pas à obtenir la valeur "30" par lui.
Mise à jour
J'ai essayé ceci mais ça ne semble pas fonctionner.
var memberExpression = (MemberExpression)GetRootConstantExpression(m);
var fi = (PropertyInfo)memberExpression.Member;
var val = fi.GetValue(((ConstantExpression)memberExpression.Expression).Value, null);
Acclamations.
Vous devez vous connecter pour publier un commentaire.
Vous pouvez compiler et d'invoquer une expression lambda dont le corps est l'accès des membres:
Locale de l'évaluation technique est fréquemment utilisée lors de l'analyse de l'expression des arbres. LINQ to SQL ne c'est exactement la chose un peu partout.
DynamicInvoke
peut être rapide @iggymoran avez-vous tester? Ou vous fait le plus rapide à taper? 😉L'expression constante va point à une capture de la classe générée par le compilateur. Je n'ai pas inclus les points de décision, etc, mais voici comment obtenir 30 de que:
price
est maintenant30
. Notez que je suis en supposant quePrice
est une propriété, mais en réalité, vous devez écrire unGetValue
méthode qui traite de la propriété /domaine.Evaluate
etTryEvaluate
ici: code.google.com/p/protobuf-net/source/browse/trunk/...MemberExpression
puis de les évaluer, ou de parvenir à sesPropertyInfo/FieldInfo
puis de les évaluer comme dansTryEvaluate
?q
est de typeList<Product>
. La Liste n'a pas de Prix des biens uniquement les Produits individuels.Le premier ou le dernier Produit aura un prix.
Si vous le savez il n'y a qu'un dans la collection, vous pouvez les aplatir à l'aide Unique
.ToList()
sur la fin, il est dans une liste.repo.Products.ToList()
est certainement une ListePouvez-vous utiliser les éléments suivants:
À l'aide de
Expression.Lambda(myParameterlessExpression).Compile().Invoke()
a plusieurs inconvénients:.Compile()
est lent. Il peut prendre plusieurs millisecondes pour terminer, même pour de petits fragments d'expression. LeInvoke
appel est super-rapide par la suite cependant, ne prend que quelques nanosecondes pour de simples expressions arithmétiques ou membre accède..Compile()
va générer (émettre) code MSIL. Cela pourrait sembler parfait (et qui explique l'excellente vitesse d'exécution), mais le problème est: Que code prend de la mémoire, qui ne peut pas être libéré avant l'application des finitions, même lorsque le GC collectées le délégué de référence!On peut éviter
Compile()
complètement pour éviter ces problèmes ou cache la compilation des délégués pour les ré-utiliser. Cette petite bibliothèque de la mine offre à la fois interprétation deExpressions
ainsi que mise en cache de compilation, où toutes les constantes et les fermetures de l'expression remplacés par d'autres paramètres automatiquement, qui sont ensuite ré-inséré dans une clôture, qui est renvoyé à l'utilisateur. Les deux processus sont bien testés, utilisés dans la production, les deux ont leurs avantages et leurs inconvénients les uns contre les autres, mais sont plus de 100 fois plus rapide queCompile()
- et d'éviter la fuite de mémoire!Et qu'est-ce exactement que vous voulez accomplir?
Parce que pour accéder à la valeur de
Price
, que vous avez à faire quelque chose comme:Si vous aviez une classe:
et une instance de l'objet:
Vous pouvez obtenir la valeur de l'Id à l'aide d'une Expression en utilisant le code suivant:
valeur contient "7"