【问题标题】:Integer contains linq c# but using using expressions整数包含 linq c# 但使用 using 表达式
【发布时间】:2018-11-16 05:09:14
【问题描述】:

我想使用 linq 表达式为我的存储库创建一个动态过滤器,我有其他过滤器,但我不知道如何使用表达式制作下一个过滤器:(条件取自 here

var result = _studentRepotory.GetAll().Where(s => 
SqlFunctions.StringConvert((double)s.Id).Contains("91")).ToList();

我有一个接收属性值的方法,propertyName 和过滤器操作符类型(枚举):

public static class Helper {
    public static Expression<Func<T, bool>> GetExpression<T>(object value, string propertyName, FilterOperatorType FilterType)
    {
        var parameter = Expression.Parameter(typeof(T));
        var property = ExpressionUtils.GetPropertyChild(parameter, propertyName);
        var constValue = Expression.Constant(value);

        BinaryExpression expresion = null;
        switch (FilterType)
        {
            case FilterOperatorType.Equal:
                expresion = Expression.Equal(property, constValue);
                break;
            case FilterOperatorType.Greater:
                expresion = Expression.GreaterThan(property, constValue);
                break;
            case FilterOperatorType.Less:
                expresion = Expression.LessThan(property, constValue);
                break;
            case FilterOperatorType.GreaterOrEqual:
                expresion = Expression.GreaterThanOrEqual(property, constValue);
                break;
            case FilterOperatorType.LessOrEqual:
                expresion = Expression.LessThanOrEqual(property, constValue);
                break;
        }

        var lambda = Expression.Lambda<Func<T, bool>>(expresion, parameter);
        return lambda;
    }
}

所以,我想添加一个新的运算符类型 Contains 来评估一个整数是否包含一些数字,在我做的第一个代码块中,但我想用 linq 表达式来做使用泛型。

最后我会:

Expression<Func<Student, bool>> where = Helper.GetExpression<Student>("91", "Id",  FilterOperatorType.Contains);
var result = _studentRepotory.GetAll().Where(where).ToList();

当 ID 包含数字 91 时,查询应该返回所有学生。

请帮助我,如果你明白,请告诉我。

【问题讨论】:

  • 没有开箱即用的方法,您需要创建一个MethodCallExpression
  • 用谷歌搜索predicatebuilder 库/类。我最近用过这个:gist.github.com/anomepani/…
  • @MrinalKamboj 我还有其他字符串过滤器,我使用的是 Expression.Call 但我不知道该怎么做。

标签: c# linq linq-expressions


【解决方案1】:

我在凌晨 2:00 还在做这个,当时大脑工作得更好嘿嘿嘿,这里是创建表情的解决方案:

object value = "91";

var parameter = Expression.Parameter(typeof(Student));
var property = ExpressionUtils.GetPropertyChild(parameter, "Id");
var constValue = Expression.Constant(value);

var expressionConvert = Expression.Convert(property, typeof(double?));

var methodStringConvert = typeof(SqlFunctions).GetMethod("StringConvert",
                    BindingFlags.Public | BindingFlags.Static, null,
                    CallingConventions.Any,
                    new Type[] { typeof(double?) },
                    null);

var methodContains = typeof(string).GetMethod("Contains", 
            BindingFlags.Public | BindingFlags.Instance,
            null, CallingConventions.Any,
            new Type[] { typeof(String) }, null);

var expresionStringConvert = Expression.Call(methodStringConvert, expressionConvert);
var expresionContains = Expression.Call(expresionStringConvert, methodContains, constValue);
var lambdaContains = Expression.Lambda<Func<Student, bool>>(expresionContains, parameter);

现在您可以在 studentRepository 的 Where 方法中使用 lambdaContains

【讨论】:

  • SqlFunctions 是什么,它是一个自定义类。您可以使用string 上的扩展方法并使用stringList&lt;string&gt; 或类似的数据结构作为输入来解决更复杂的用例。在扩展方法中,您可以解决更复杂的用例,但只是需要在同一内存中使用它或使用表达式序列化器
  • @MrinalKamboj SqlFunctions 是 EntityFramework 包中带有辅助函数的静态类。 View reference here
【解决方案2】:

这里有一个方法。您可以将 int 列搜索为字符串

https://gist.github.com/gnncl/e424adefc3e08b607beee8d638759492

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 2020-07-30
    • 1970-01-01
    • 2016-10-01
    • 2018-09-29
    相关资源
    最近更新 更多