【问题标题】:Extension Method with dynamically built linq predicate具有动态构建的 linq 谓词的扩展方法
【发布时间】:2010-10-21 00:03:58
【问题描述】:

我有这个扩展方法。

        public static IQueryable<T> SearchBy<T>(this IQueryable<T> source, SearchCriteria criteria)
    {
        //throw an error if the source is null
        if (source == null)
        {
            throw new ArgumentNullException("source");
        }

        ParameterExpression parameter = Expression.Parameter(source.ElementType, string.Empty);
        var property = Expression.Equal(Expression.PropertyOrField(parameter, criteria.Property), Expression.Constant(criteria.PropertyValue));
        LambdaExpression lambda = Expression.Lambda(property, parameter);

        Expression methodCallExpression = Expression.Call(typeof(Queryable), "SelectMany",
                                            new Type[] { source.ElementType, property.Type },
                                            source.Expression, Expression.Quote(lambda));

        return source.Provider.CreateQuery<T>(methodCallExpression);
    }

我收到这个错误

 No method 'SelectMany' on type 'System.Linq.Queryable' is compatible with the         supplied arguments.
    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.InvalidOperationException: No method 'SelectMany' on type 'System.Linq.Queryable' is compatible with the supplied arguments.

Source Error:

Line 67:             LambdaExpression lambda = Expression.Lambda(property, parameter);
Line 68: 
Line 69:             Expression methodCallExpression = Expression.Call(typeof(Queryable), "SelectMany",
Line 70:                                                 new Type[] { source.ElementType, property.Type },
Line 71:                                                 source.Expression, Expression.Quote(lambda));

当我像这样从实体框架调用这个方法时

this.grdReservations.DataSource = dataContext.CustomerSet.SearchBy(crit);

这是搜索条件

        SearchCriteria crit = new SearchCriteria();
        crit.Property = "UserName";
        crit.PropertyValue = "new_user";
        crit.Search = SearchType.Equal;

如果有人能看一看并推动我朝着正确的方向前进,我会非常高兴。

感谢您的宝贵时间。

编辑:我在家,所以我无法测试,但我尝试的任何方法(“Select”、“Where”、“SelectMany”)都返回了这个错误,所以我假设我正在做其他事情错误的。

【问题讨论】:

    标签: c# linq extension-methods


    【解决方案1】:

    您要调用 SelectMany 还是只调用 Select?

    SelectMany 需要一个 lambda,它返回一个 IEnumerable[TResult] 而不是 TResult。

    【讨论】:

    • 两者都返回相同的错误。事实上,我放在那里的任何东西都会返回错误。
    • 您必须确保 Expression.Call 方法中最后一个参数的类型与作为第二个参数传递的名称的方法所期望的参数相匹配。
    【解决方案2】:
     this works
    
    public static IQueryable<T> SearchBy<T>(this IQueryable<T> source, SearchCriteria criteria)
        {
            //throw an error if the source is null
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }
    
            ParameterExpression parameter = Expression.Parameter(source.ElementType, string.Empty);
            BinaryExpression property = Expression.Equal(Expression.PropertyOrField(parameter, criteria.Property), Expression.Constant(criteria.PropertyValue));
            LambdaExpression lambda = Expression.Lambda(property, parameter);
    
            Expression methodCallExpression = Expression.Call(typeof(Queryable), "Where",
                                                new Type[] { source.ElementType },
                                                source.Expression, Expression.Quote(lambda));
    
            return source.Provider.CreateQuery<T>(methodCallExpression);
        }
    

    我需要将 Expression.Call 类型数组更改为此

    new Type[] { source.ElementType }
    

    This Example 帮助很大。

    感谢您的宝贵时间

    【讨论】:

      【解决方案3】:

      lambda 似乎采用 T 类型的参数值并返回一个布尔值。看起来它应该返回一个 IEnumerable 。

      或者,如果您将“SelectMany”更改为“Select”,则 lambda 将需要返回 T 类型的值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-09-22
        • 1970-01-01
        • 2016-02-05
        • 1970-01-01
        • 1970-01-01
        • 2010-09-08
        • 1970-01-01
        相关资源
        最近更新 更多