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

Posted

技术标签:

【中文标题】如何创建表达式树以执行与“StartsWith”相同的操作【英文标题】:How to create an Expression tree to do the same as "StartsWith" 【发布时间】:2010-12-29 11:51:29 【问题描述】:

目前,我有这种方法来比较两个数字

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 子句,基于一个属性和一个值。 Y 可以构造 Lessthan、LessOrEqualThan 等等价物,因为 System.Linq.Expressions.Expression 已预定义此运算符。

¿如何转换此代码以对字符串执行相同的操作? System.Linq.Expressions.Expression 没有给我一个预定义的运算符,比如“包含”或“startwith”,我真的不喜欢表达式树。

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

【问题讨论】:

【参考方案1】:
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 谢谢,确实。 汤姆——你先生是个英雄【参考方案2】:

它不是一个操作符,而是一个方法,所以你可以用Expression.Call()来调用它,其中methodinfo参数是typeof(string).GetMethod("StartsWith")。

【讨论】:

我正在阅读它,但我之前没有使用过表达式树。 ¿你能给我一个例子吗?

以上是关于如何创建表达式树以执行与“StartsWith”相同的操作的主要内容,如果未能解决你的问题,请参考以下文章

构建动态表达式树以过滤集合属性

表达式树 Expression Trees

改变谓词的表达式树以针对另一种类型

是否可以解释 C# 表达式树以发出 JavaScript?

[C#] 说说表达式树 - Expression Trees

如何在 scipy 创建的树状图中获得与颜色簇相对应的平面聚类