【问题标题】:Dynamic Lambda condition on nested array嵌套数组上的动态 Lambda 条件
【发布时间】:2015-02-17 06:30:25
【问题描述】:

我想在一个带有字符串数组的集合中执行一个动态 Lambda:

public class ClassStudentsViewModel
{
    public string[] Disciplines { get; set; }
    public TeacherName { get; set; }
}

这就是我正在尝试的:

sourceClassStudentsViewModel 的集合,values 是一个字符串数组。执行时,它会抛出这个异常:

“字符串”类型中不存在属性或字段“y”

经过一番搜索,我发现this question 几乎是同样的问题,并且OP 结束了更改 Dynamic.cs 的源代码,这对我来说不是一个好的选择。我想知道我正在尝试的内容不受支持或可能是错误。问题是上面提到的问题是差不多 4 年前提出的。

下面的 sn-p 很好用:

classStudents.AsQueryable().Where(x => x.Disciplines.Any(y => y == "Turma 2")).ToList();

我怎样才能摆脱这个错误?

更新:

我正在尝试的一些上下文:我的控制器接收到一个 viewModel,其中包含由 3rd 方网格发送的过滤器集合,其中基本上包含一个 value 和一个 operator em>,例如eqgt 等... 一个方法循环所有这些过滤器并在 lambda 运算符上进行转换,例如 eq==contains.Contains()。在像TeacherName(上面更新的viewModel)这样的简单字符串属性中,动态过滤器可以工作,例如如果屏幕截图中的predicate 是:"TeacherName.Contains(@0)",则效果很好。

更新 2:

此代码生成谓词:

public static string ToLambdaOperator(string field, string oper, int index, string sufix = null)
{
    var result = String.Empty;

    switch (oper)
    {
        case "eq":
        case "neq":
        case "gte":
        case "gt":
        case "lte":
        case "lt":
            result = string.Format(field + ToLinqOperator(oper) + "@" + index);
            break;

        case "startswith":
            result = field + ".StartsWith(" + "@" + index + ")";
            break;

        case "endswith":
            result = field + ".EndsWith(" + "@" + index + ")";
            break;

        case "contains":
            result = field + ".Contains(" + "@" + index + ")";
            break;

        case "doesnotcontain":
            result = "!" + field + ".Contains(" + "@" + index + ") || " + field + ".Equals(String.Empty)";
            break;
    }

    if (!String.IsNullOrEmpty(sufix))
    {
        result += sufix;
    }

    return result;
}

// Use example
var operator = "eq";
var paramCounter = -1;
var predicate = ToLambdaOperator("Disciplines.Any(y => y", operator, ++paramCounter, ")");

上面的谓词将产生:Disciplines.Any(y => y == @0)。使用运算符contains 将导致:Disciplines.Any(y => y.Contains(@0))

【问题讨论】:

  • 这里完全不清楚为什么需要使用动态 LINQ。你的情况是什么?
  • @JonSkeet 我在外部构建该表达式以过滤 3rd 方网格小部件。
  • 这不是一个非常清楚的描述——它没有给我们更多的背景信息。您能否使用普通 LINQ to Objects 执行查询的 this 部分,然后将其用作小部件集成的动态 LINQ 源?
  • @JonSkeet 我试图在不发布数百行的情况下包含所有相关信息。我已经更新了,我希望它能解决这个问题。顺便说一句,我链接this 的问题在不同的解释中有同样的问题。
  • 如果您已经在编写代码来分别处理每个运算符,我不明白您为什么要使用动态 LINQ - 我只需将每个运算符转换为 Func<T, bool>相关类型...您在“普通”LINQ to Objects 中可以做的越多,就越容易。

标签: c# linq lambda dynamic-linq


【解决方案1】:

我认为您要做的是根据提供的参数生成表达式树。以下是一些有关如何执行此操作的示例。

https://gist.github.com/afreeland/6733381

How to: Use Expression Trees to Build Dynamic Queries (C# and Visual Basic)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-22
    • 2021-07-15
    • 1970-01-01
    • 1970-01-01
    • 2020-08-23
    • 2011-01-29
    • 1970-01-01
    相关资源
    最近更新 更多