Comparaison de chaînes d'arborescence d'expression Linq

expression-trees linq

Question

J'essaie de construire un arbre d'expression pour fonctionner contre un tableau de chaînes. Je dois comprendre comment utiliser la méthode Equal.

Quelqu'un pourrait-il me donner un exemple de
1) en utilisant la méthode Expression.Equal (ou .Equals) pour comparer une chaîne à une constante, et
2) en utilisant une expression de quelque type que ce soit pour utiliser la méthode string.Contains () à des fins de filtrage.

J'essaie d'apprendre les mécanismes d'Expression Tree, mais je n'ai pas encore trouvé de bon tutoriel. J'apprécie beaucoup votre aide.

string[] arr = {"s1","s2","s3"};
IQueryable<String> queryableData = arr.AsQueryable<string>();

// what should go below here?
ParameterExpression p1 = Expression.Parameter(typeof(string), "c");
Expression left = Expression.Constant("s2");
Expression e1 = Expression.Equal(left, p1);

IQueryable<string> res = queryableData.Provider.CreateQuery<string>(e2);

Réponse acceptée

Aaah, je vois ce que vous demandez ... Et vous entrez vraiment dans des eaux très troubles, un des rares domaines avec lesquels les bibliothèques de réflexion .NET ne sont pas belles. Vous devez créer une expression d'appel pour appeler Queryable.Where () sur l'objet queryableData, puis créer une nouvelle requête utilisant cette expression ... Le problème est que l'obtention d'une version générique d'une méthode dans .NET n'est pas nécessairement la plus simple. chose que vous avez jamais vue dans votre vie:

MethodCallExpression call = Expression.Call(
    null, // Calling Queryable.Where(), extension method, not instance method
    getGenericMethod<string>(typeof(Queryable), "Where", typeof(IQueryable<string>), typeof(Expression<Func<string,bool>>)),
    Expression.Constant(queryableData),
    Expression.Lamda(
       e1,
       p1)
);
IQueryable<string> res = queryableData.Provider.CreateQuery<string>(call);

Vous devez également définir getGenericMethod (vous pouvez trouver de meilleures implémentations pour cela en ligne à d’autres endroits, c’est vraiment une approche assez simple):

MethodCallExpression call = Expression.Call(
    null, // Calling Queryable.Where(), extension method, not instance method
    getGenericMethod<string>(typeof(Queryable), "Where", typeof(IQueryable<string>), typeof(Expression<Func<string,bool>>)),
    Expression.Constant(queryableData),
    Expression.Lamda(
       e1,
       p1)
);
IQueryable<string> res = queryableData.Provider.CreateQuery<string>(call);

Il y a presque sans doute quelques erreurs, mais j'espère que vous pourrez voir où aller à partir de là ...


Réponse populaire

Juste pour donner ma solution:

string[] arr = {"s1","s2","s3"};
IQueryable<String> queryableData = arr.AsQueryable<string>();
ParameterExpression pe = Expression.Parameter(typeof(string), "company");
Expression right = Expression.Constant("on");
Expression left = Expression.Call(pe, typeof(string).GetMethod("Contains"), right);
MethodCallExpression e2 = Expression.Call(
            typeof(Queryable),
            "Where",
            new Type[] { queryableData.ElementType },
            queryableData.Expression,
            Expression.Lambda<Func<string, bool>>(left, new ParameterExpression[] { pe }));

IQueryable<string> res = queryableData.Provider.CreateQuery<string>(e2);



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi