Kombinieren mehrerer Ausdrücke (Ausdruck <Func<T,bool> &gt;) nicht mit Variablen arbeiten. Warum?

expression-trees foreach lambda linq

Frage

ok Leute, bloß mit mir. Ich fasse zuerst zusammen, gehe dann ins Detail.

Ich habe eine Reihe von Methoden geschrieben (.WhereOr, .WhereAnd), die es mir erlauben, eine Menge Lambda-Abfragen zu "stapeln" und sie dann auf eine Sammlung anzuwenden. Zum Beispiel wäre die Verwendung mit Datensätzen etwas ähnlich (obwohl es mit jeder Klasse unter Verwendung von Generika funktioniert):

MIT LINQ TO DATASETS (Verwenden der .NET DataSetExtensions)

DataTable Result;

List<Expression<Func<DataRow, bool>> Queries = new List<Expression<Func<DataRow, bool>>();

Queries.Add(dr=> dr.Field<string>("field1") == "somestring");
Queries.Add(dr=> dr.Field<string>("field2") == "somestring"); 
Queries.Add(dr=> dr.Field<string>("field3") == "somestring"); 

Result = GetSomeTable().AsEnumarable().WhereOr(Queries).CopyToDataTable();

Nun sagen Sie, dass im obigen Beispiel nur eine Zeile in der Sammlung mit "somestring" übereinstimmt und es im Feld "field2" steht.

Das bedeutet, dass die Anzahl für Ergebnis 1 sein sollte.

Nun, sagen wir, ich schreibe den obigen Code etwas zu:

DataTable Result;

List<Expression<Func<DataRow, bool>> Queries = new List<Expression<Func<DataRow, bool>>();

Queries.Add(dr=> dr.Field<string>("field1") == "somestring");
Queries.Add(dr=> dr.Field<string>("field2") == "somestring"); 
Queries.Add(dr=> dr.Field<string>("field3") == "somestring"); 

Result = GetSomeTable().AsEnumarable().WhereOr(Queries).CopyToDataTable();

Nun, ich verstehe Ausdrücke nicht wirklich, aber für mich machen beide obigen Beispiele genau dasselbe.

Außer, dass "Ergebnis" im ersten Beispiel eine Zählung von 1 hat, und "Ergebnis" im zweiten Beispiel hat eine Zählung von 0.

Wenn Sie in den Listenspalten im zweiten Beispiel "field2" als letztes und nicht als zweites setzen, hat "Result" korrekt den Wert 1.

Von alldem bin ich zu einer Art Schlussfolgerung gekommen, aber ich verstehe nicht wirklich, was passiert, noch wie ich es beheben kann. Kann ich diese Ausdrücke früher ... oder einen Teil davon "bewerten"?

FAZIT:

Im Grunde scheint es, wenn ich wörtliche Werte dorthin sende, wie "field1", funktioniert es. Aber wenn ich Variablen wie "col" einsende, funktioniert das nicht, weil diese "Ausdrücke" erst viel später im Code ausgewertet werden.

Das würde auch erklären, warum es funktioniert, wenn ich "field2" auf die letzte Position verschiebe. es funktioniert, weil die Variable "col" zuletzt "field2" zugewiesen wurde, also zu dem Zeitpunkt, zu dem die Ausdrücke "col" gleich "field2" auswerten.

Ok, also, gibt es einen Weg um dies ??

Hier ist der Code für meine WhereOr-Methode (es ist eine Erweiterungsmethode für IENumerable):

DataTable Result;

List<Expression<Func<DataRow, bool>> Queries = new List<Expression<Func<DataRow, bool>>();

Queries.Add(dr=> dr.Field<string>("field1") == "somestring");
Queries.Add(dr=> dr.Field<string>("field2") == "somestring"); 
Queries.Add(dr=> dr.Field<string>("field3") == "somestring"); 

Result = GetSomeTable().AsEnumarable().WhereOr(Queries).CopyToDataTable();

Akzeptierte Antwort

Die "wie zu beheben" Antwort. Ändere das:

string col;
foreach(string c in columns) {
    col = c;
    Queries.Add(dr=> dr.Field<string>(col) == "somestring");
} 

zu diesem:

string col;
foreach(string c in columns) {
    col = c;
    Queries.Add(dr=> dr.Field<string>(col) == "somestring");
} 

Genießen. Die Antwort "What & Why" wurde von Brian gegeben.





Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum