【问题标题】:How to create an Expression tree to do the same as "StartsWith"如何创建表达式树以执行与“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 中发布您的答案。选择让您感觉更舒适的那个。

【问题讨论】:

    标签: c# .net vb.net lambda expression-trees


    【解决方案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")。

    【讨论】:

    • 我正在阅读它,但我之前没有使用过表达式树。 ¿你能给我一个例子吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    相关资源
    最近更新 更多