Ich möchte ein dynamisches Lambda in einer Sammlung mit einem Array von Zeichenfolgen [] ausführen:
public class ClassStudentsViewModel
{
public string[] Disciplines { get; set; }
public TeacherName { get; set; }
}
Das versuche ich:
Die source
ist eine Sammlung von ClassStudentsViewModel
und die values
sind ein Array von Zeichenfolgen mit einer Zeichenfolge. Wenn es ausgeführt wird, wirft es mir diese Ausnahme:
Im Typ 'String' ist keine Eigenschaft oder kein Feld 'y' vorhanden.
Nach einigem Suchen habe ich diese Frage gefunden , die fast das gleiche Problem darstellt, und das OP hat die Änderung des Quellcodes von Dynamic.cs beendet. Das ist keine gute Option für mich. Ich frage mich, was ich versuche, wird nicht unterstützt oder könnte ein Fehler sein. Das Problem ist, dass die oben genannte Frage vor fast 4 Jahren gestellt wurde.
Das folgende Snippet funktioniert gut:
classStudents.AsQueryable().Where(x => x.Disciplines.Any(y => y == "Turma 2")).ToList();
Wie kann ich diesen Fehler beseitigen?
AKTUALISIEREN:
Ein kleiner Kontext dessen, was ich versuche: Mein Controller empfängt ein viewModel mit einer Sammlung von Filtern, die vom Raster eines Drittanbieters gesendet werden und im Grunde einen Wert und einen Operator wie eq
, gt
usw. enthalten. Eine Methode durchläuft alle diese Filter und transformiert Lambda-Operatoren wie eq
to ==
oder contains
to .Contains()
. In einer einfachen Zeichenfolgeeigenschaft wie TeacherName
(aktualisiertes viewModel oben) funktionieren die dynamischen Filter, z. B. wenn das predicate
im Screenshot lautet: "TeacherName.Contains(@0)"
, funktioniert es gut.
UPDATE 2:
Dieser Code generiert das Prädikat:
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, ")");
Das obige Prädikat ergibt: Disciplines.Any(y => y == @0)
. Mit dem Operator contains
ergibt sich: Disciplines.Any(y => y.Contains(@0))
.
Ich denke, Sie versuchen, einen Ausdrucksbaum basierend auf den angegebenen Argumenten zu generieren. Hier sind einige Beispiele, wie das geht.
https://gist.github.com/afreeland/6733381
Gewusst wie: Verwenden von Ausdrucksbäumen zum Erstellen dynamischer Abfragen (C # und Visual Basic)