开发者

Extension Method with dynamically built linq predicate

I have this extension method.

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

I get this error

 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开发者_如何学Python:                                                 source.Expression, Expression.Quote(lambda));

when I call this method from the entity framework like this

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

this is SearchCriteria

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

If anyone could take a look and give me a push in the right direction I'd be very happy.

Thanks for your time.

Edit: I'm home so I can't test but any method I try ("Select", "Where", "SelectMany") have all returned this error, so I'm assuming I'm doing something else wrong.


Do you want to call SelectMany or just Select?

SelectMany expects a lambda the returns an IEnumerable[TResult] not TResult.


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

I needed to change the Expression.Call type array to this

new Type[] { source.ElementType }

This Example helped very much.

Thanks for your time guys


The lambda appears to take a parameter value of type T and return a bool. It looks like it should be returning an IEnumerable instead.

Or, if you change "SelectMany" to "Select", the lambda would need to return a value of type T.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜