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

发布于 2024-09-28 13:03:22 字数 2408 浏览 3 评论 0原文

我有这个扩展方法。

        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

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

如果有人可以看一下并给我一个正确的方向推动,我会非常高兴。

感谢您抽出时间。

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

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:                                                 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

万水千山粽是情ミ 2024-10-05 13:03:22

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

SelectMany 期望 lambda 返回 IEnumerable[TResult] 而不是 TResult。

Do you want to call SelectMany or just Select?

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

满意归宿 2024-10-05 13:03:22
 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 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

梅窗月明清似水 2024-10-05 13:03:22

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

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文