在NetCore上包含包含的Lambda表达式

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在NetCore上包含包含的Lambda表达式相关的知识,希望对你有一定的参考价值。

好家伙们。

我有一个问题,当我尝试使用Expression.Builder构建Lambda表达式时,代码抛出错误。

说:“静态方法需要null实例,非静态方法需要non-null实例。”

我已经成功使用简单的表达式,如:

IQueryable<PersonTestModel> expected = data.Where(x => x.IsActive);


PersonTestModel expected = data.FirstOrDefault(x => x.Id != 3);


IQueryable<PersonTestModel> expected = data.Where(x => x.FirstName.StartsWith("a", StringComparison.InvariantCultureIgnoreCase));


IQueryable<PersonTestModel> expected = data.Where(x => x.Balance > averageBalance);

但是,我无法构建此表达式

var dataFilter = new HashSet<int>  2 ;
IQueryable<PersonTestModel> data = await PersonFaker.GetFakeSimpleData(60);

//this is expression i will try
Expression<Func<PersonTestModel, bool>> func = x => dataFilter.Contains(x.UserId);
var expected = data.Where(func);

这是我的代码,用于构建通用表达式:

private static Expression GetExpression<T>(ParameterExpression parameter, QueryFilter queryFilter)
        
            MemberExpression member = Expression.Property(parameter, queryFilter.PropertyName);
            ConstantExpression constant = GetConstant(member.Type, queryFilter.Value);

            switch (queryFilter.Operator)
            
                case Operator.Equals:
                    return Expression.Equal(member, constant);
                case Operator.NotEqual:
                    return Expression.NotEqual(member, constant);
                case Operator.Contains:
                case Operator.StartsWith:
                case Operator.EndsWith:
                    
                        constant = GetConstant(member.Type, queryFilter.Value.ToUpper());
                        return Expression.Call(Expression.Call(member, "ToUpper", null), queryFilter.Operator.ToString(), null, constant);
                    
                case Operator.GreaterThan:
                    return Expression.GreaterThan(member, constant);
                case Operator.GreaterOrEqualThan:
                    return Expression.GreaterThanOrEqual(member, constant);
                case Operator.LessThan:
                    return Expression.LessThan(member, constant);
                case Operator.LessOrEqualThan:
                    return Expression.LessThanOrEqual(member, constant);
                default:
                    throw new Exception($"The type queryFilter.Operator not is a type selector valid.");
            
        

但是使用该表达式我收到了一条错误消息,这是代码

private static Expression GetComplexExpression<T>(ParameterExpression parameter, QueryFilter queryFilter)

    MemberExpression member = Expression.PropertyOrField(parameter, queryFilter.PropertyName);

    MethodInfo method = typeof(HashSet<int>).GetMethods(BindingFlags.Public | BindingFlags.Instance)
        .Single(x => x.Name == "Contains" && x.IsFinal && x.GetParameters().Length == 1);
    var constant = Expression.Constant(queryFilter.Values);
    MethodCallExpression methodCallExpression = Expression.Call(method, constant, member);

    return methodCallExpression;

我在google上搜索,但搜索的唯一结果是stackoverflow上的以下代码:

Build Lambda Expressions with Contains非常感谢您的关注...

答案

继续尝试后,我找到了解决我问题的方法,上面的代码已关闭。

private static Expression GetComplexExpression<T>(ParameterExpression parameter, QueryFilter queryFilter)

    MemberExpression value = Expression.PropertyOrField(parameter, queryFilter.PropertyName);

    MethodInfo method = typeof(HashSet<string>)
        .GetMethods(BindingFlags.Public | BindingFlags.Instance)
        .Single(x => x.Name == "Contains" && x.IsFinal && x.GetParameters().Length == 1);

    ConstantExpression listContains = Expression.Constant(queryFilter.Values);

    MethodCallExpression body = Expression.Call(listContains, method, value);

    return body;

我仅为此更改使用的方法

public static MethodCallExpression Call(Expression instance, MethodInfo method, params Expression[] arguments);

希望我的回答能帮助其他人。

以上是关于在NetCore上包含包含的Lambda表达式的主要内容,如果未能解决你的问题,请参考以下文章

表达式不能包含 lambda 表达式

表达式树 lambda 可能不包含空传播运算符

lambda 函数是不是可以包含 Razor 语法并在视图中执行?

错误:对于带有 from 的 Linq,“表达式树 lambda 可能不包含空传播运算符”

List集合 遍历 四种方式(包含 Lambda 表达式遍历)

Lambda表达式的简单使用