我想在一个带有字符串数组[]的集合中执行动态Lambda:
public class ClassStudentsViewModel
{
public string[] Disciplines { get; set; }
public TeacherName { get; set; }
}
这就是我正在尝试的:
source
是ClassStudentsViewModel
的集合,values
是一个包含一个字符串的字符串数组。执行时,它会抛出这个异常:
“String”
类型中不存在属性或字段“y”
经过一番搜索后,我发现this question几乎是同一个问题,OP结束了更改 Dynamic.cs的源代码,这对我来说不是一个不错的选择。我想知道我正在尝试的是不支持或可能是一个错误。问题在于,大约4年前就提到了上述问题。
以下代码段效果不错:
classStudents.AsQueryable().Where(x => x.Disciplines.Any(y => y == "Turma 2")).ToList();
如何摆脱这个错误?
更新
我正在尝试的一些上下文:我的控制器收到一个viewModel,其中包含第三方网格发送的一组过滤器,其中基本上包含值和运算符,如eq
,gt
等...一个方法循环所有这些过滤器并将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))
。
答案 0 :(得分:1)
我认为你要做的是根据提供的参数生成表达式树。以下是有关如何执行此操作的一些示例。
https://gist.github.com/afreeland/6733381
How to: Use Expression Trees to Build Dynamic Queries (C# and Visual Basic)