string []の配列を含むコレクションでDynamic Lambdaを実行したい:
public class ClassStudentsViewModel
{
public string[] Disciplines { get; set; }
public TeacherName { get; set; }
}
これは私が試していることです:
source
はClassStudentsViewModel
コレクションで、 values
は1つの文字列を持つ文字列の配列です。実行すると、次の例外がスローされます。
タイプ 'String'にプロパティまたはフィールド 'y'が存在しません
いくつか検索したところ、ほぼ同じ問題であるこの質問が見つかりました。OPがDynamic.csのソースコードの変更を終了しました。これは、私にとっては良いオプションではありません。私がしようとしていることはサポートされていないか、バグかもしれません。問題は、上記の質問がほぼ4年前に行われたことです。
次のスニペットはうまくいきます:
classStudents.AsQueryable().Where(x => x.Disciplines.Any(y => y == "Turma 2")).ToList();
どうすればそのエラーを取り除くことができますか?
更新:
私がしようとしていることの小さなコンテキスト:私のコントローラーは、サードパーティグリッドによって送信されたフィルターのコレクションを含むviewModelを受け取ります。これには、基本的にeq
やgt
などの値と演算子が含まれています...メソッドはこれらのフィルターをすべてループします等ラムダ演算子に変換、 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))
。
あなたがしようとしているのは、提供された引数に基づいて式ツリーを生成することだと思います。これを行う方法に関するいくつかの例を次に示します。