Comment créer un arbre d'expression pour faire la même chose que "StartsWith"

.net c# expression-trees lambda vb.net

Question

Actuellement, j'ai cette méthode pour comparer deux nombres

Private Function ETForGreaterThan(ByVal query As IQueryable(Of T), ByVal propertyValue As Object, ByVal propertyInfo As PropertyInfo) As IQueryable(Of T)

    Dim e As ParameterExpression = Expression.Parameter(GetType(T), "e")
    Dim m As MemberExpression = Expression.MakeMemberAccess(e, propertyInfo)
    Dim c As ConstantExpression = Expression.Constant(propertyValue, propertyValue.GetType())
    Dim b As BinaryExpression = Expression.GreaterThan(m, c)
    Dim lambda As Expression(Of Func(Of T, Boolean)) = Expression.Lambda(Of Func(Of T, Boolean))(b, e)
    Return query.Where(lambda)

End Function

Cela fonctionne bien et est consommé de cette façon

query = ETForGreaterThan(query, Value, propertyInfo)

Comme vous pouvez le constater, je lui attribue une collection IQueryable et y ajoute une clause where, basée sur une propriété et une valeur. Y peut construire les équivalents Lessthan, LessOrEqualThan, etc. comme System.Linq.Expressions.Expression a ces opérateurs prédéfinis.

«Comment puis-je transformer ce code pour faire la même chose avec des chaînes? System.Linq.Expressions.Expression ne me donne pas d'opérateur prédéfini tel que "contient" ou "startwith" et je ne suis vraiment pas avec les arbres d'expression

Merci et merci de poster votre réponse en C # / VB. Choisissez celui qui vous fait sentir plus à l'aise.

Réponse acceptée

using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;

namespace WindowsFormsApplication1
{
    static class Program
    {
        [STAThread]
        static void Main()
        {
            using (var context = new NorthwindEntities())
            {
                PropertyInfo propertyInfo = typeof(Customer).GetProperty("CustomerID"); 

                IQueryable<Customer> query = context.Customers;
                query = ETForStartsWith<Customer>(query, "A", propertyInfo); 
                var list = query.ToList();
            }
        }

        static IQueryable<T> ETForStartsWith<T>(IQueryable<T> query, string propertyValue, PropertyInfo propertyInfo)
        {
            ParameterExpression e = Expression.Parameter(typeof(T), "e");
            MemberExpression m = Expression.MakeMemberAccess(e, propertyInfo);
            ConstantExpression c = Expression.Constant(propertyValue, typeof(string));
            MethodInfo mi = typeof(string).GetMethod("StartsWith", new Type[] { typeof(string) });
            Expression call = Expression.Call(m, mi, c);

            Expression<Func<T, bool>> lambda = Expression.Lambda<Func<T, bool>>(call, e); 
            return query.Where(lambda);
        }
    }
}

Réponse populaire

Ce n'est pas un opérateur, mais une méthode, vous pouvez donc l'appeler avec Expression.Call (), où le paramètre methodinfo sera typeof (chaîne) .GetMethod ("StartsWith").



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow