代码之家  ›  专栏  ›  技术社区  ›  jim

动态构建linq谓词的扩展方法

  •  1
  • jim  · 技术社区  · 15 年前

    我有这个扩展方法。

            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”、“Select m any”)都返回了这个错误,所以我假设我做错了其他事情。

    3 回复  |  直到 15 年前
        1
  •  1
  •   Jakub Konecki    15 年前

    要调用SelectMany还是只调用Select?

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

        2
  •  1
  •   jim    15 年前
     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);
        }
    

    我需要更改表达式。调用类型数组

    new Type[] { source.ElementType }
    

    This Example 帮助很大。

    谢谢你们的时间伙计们

        3
  •  0
  •   Jack Leitch    15 年前

    lambda似乎接受T类型的参数值并返回bool。看起来应该返回一个IEnumerable。