如何创建一个表达式树,以执行与“StartsWith”相同的操作

14

目前,我有这样一种比较两个数字的方法:

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

它工作得很好,可以这样使用

query = ETForGreaterThan(query, Value, propertyInfo)

您可以看到,我给了一个IQueryable集合,并在其上添加了where子句,基于属性和值。您可以构造Lessthan、LessOrEqualThan等等与System.Linq.Expressions.Expression预定义的操作符等价的表达式。

如何将此代码转换为处理字符串?System.Linq.Expressions.Expression没有像“contains”或“startwith”这样的预定义运算符,而且我对表达式树非常陌生。

谢谢,答案请用C# / VB发布。选择让您感觉更舒适的那个。

2个回答

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

测试并且再次工作。不到24小时的两倍。汤姆,有没有可能给你买一杯啤酒?:D 非常感谢。 - Jonathan
汤姆先生,您是一个英雄。 - whiteshooz

5

这不是一个运算符,而是一个方法,因此您可以使用Expression.Call()调用它,其中methodinfo参数将是typeof(string).GetMethod("StartsWith")。


我正在了解它,但我以前没有使用过表达式树。你能给我提供一个例子吗? - Jonathan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接