【发布时间】:2015-02-17 06:30:25
【问题描述】:
我想在一个带有字符串数组的集合中执行一个动态 Lambda:
public class ClassStudentsViewModel
{
public string[] Disciplines { get; set; }
public TeacherName { get; set; }
}
这就是我正在尝试的:
source 是ClassStudentsViewModel 的集合,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>,例如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))。
【问题讨论】:
-
这里完全不清楚为什么需要使用动态 LINQ。你的情况是什么?
-
@JonSkeet 我在外部构建该表达式以过滤 3rd 方网格小部件。
-
这不是一个非常清楚的描述——它没有给我们更多的背景信息。您能否使用普通 LINQ to Objects 执行查询的 this 部分,然后将其用作小部件集成的动态 LINQ 源?
-
@JonSkeet 我试图在不发布数百行的情况下包含所有相关信息。我已经更新了,我希望它能解决这个问题。顺便说一句,我链接this 的问题在不同的解释中有同样的问题。
-
如果您已经在编写代码来分别处理每个运算符,我不明白您为什么要使用动态 LINQ - 我只需将每个运算符转换为
Func<T, bool>相关类型...您在“普通”LINQ to Objects 中可以做的越多,就越容易。
标签: c# linq lambda dynamic-linq