嵌套数组上的动态Lambda条件

时间:2014-12-23 12:08:43

标签: c# linq lambda dynamic-linq

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

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

这就是我正在尝试的:

enter image description here

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

  

“String”

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

经过一番搜索后,我发现this question几乎是同一个问题,OP结束了更改 Dynamic.cs的源代码,这对我来说不是一个不错的选择。我想知道我正在尝试的是不支持或可能是一个错误。问题在于,大约4年前就提到了上述问题。

以下代码段效果不错:

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

如何摆脱这个错误?

更新

我正在尝试的一些上下文:我的控制器收到一个viewModel,其中包含第三方网格发送的一组过滤器,其中基本上包含运算符,如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))

1 个答案:

答案 0 :(得分:1)

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

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

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