Combinaison de plusieurs expressions (Expression <Func<T,bool> &gt;) ne fonctionne pas avec des variables. Pourquoi?

expression-trees foreach lambda linq

Question

ok les gars, nu avec moi. Je vais résumer d'abord, puis entrer dans les détails.

J'ai écrit un certain nombre de méthodes (.WhereOr, .WhereAnd) qui me permettent essentiellement d'empiler un ensemble de requêtes lambda, puis de les appliquer à une collection. Par exemple, l'utilisation avec des ensembles de données ressemblerait un peu à ceci (bien que cela fonctionne avec n'importe quelle classe en utilisant des génériques):

WITH LINQ TO DATASETS (Utilisation des .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();

Supposons maintenant que dans l'exemple ci-dessus, une seule ligne de la collection corresponde à "somestring" et figure dans le champ "field2".

Cela signifie que le nombre de résultats devrait être 1.

Maintenant, disons que je réécris légèrement le code ci-dessus à ceci:

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();

Maintenant, je ne comprends pas vraiment les expressions, mais pour moi, les deux exemples ci-dessus font exactement la même chose.

Sauf que "Résultat" dans le premier exemple a un compte de 1 et "Résultat" dans le deuxième exemple a un compte de 0.

De même, dans les colonnes List du deuxième exemple, si vous mettez "field2" last au lieu de second, "Result" a correctement le compte 1.

Donc, de tout cela, je suis arrivé à une sorte de conclusion, mais je ne comprends pas vraiment ce qui se passe, ni comment le réparer ..? Puis-je "évaluer" ces expressions plus tôt ... ou une partie d'entre elles?

CONCLUSION:

En gros, il semble que si j’envoie des valeurs littérales, comme "field1", cela fonctionne. Mais si j'envoie des variables, comme "col", cela ne fonctionne pas, car ces "expressions" ne sont évaluées que beaucoup plus tard dans le code.

cela expliquerait également pourquoi cela fonctionne lorsque je déplace "field2" à la dernière position. cela fonctionne parce que la variable "col" a été affectée à "champ2" enfin, donc au moment où les expressions évaluent "col" est égal à "champ2".

Ok, y a-t-il un moyen de contourner cela ??

Voici le code de ma méthode WhereOr (c'est une méthode d'extension à 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();

Réponse acceptée

La réponse "comment réparer". Change ça:

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

pour ça:

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

Prendre plaisir. Brian a donné la réponse "quoi et pourquoi".


Réponse populaire




Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi