while ultimo sirve registro que programacion para lenguaje hace explicacion ejemplo bucles c# linq

c# - ultimo - La consulta de Linq incorporada en el bucle foreach siempre toma el valor del parámetro de la última iteración



que hace do en c++ (3)

Tengo una lista que contiene varias palabras clave. Los busqué construyendo mi consulta linq con ellos de esa manera (reducida para eliminar el ruido del código):

List<string> keys = FillKeys() foreach (string key in keys){ q = q.Where(c => c.Company.Name.Contains(key)); }

Cuando hago que mis teclas contengan 2 claves que devuelven los resultados por separado, pero nunca pueden ocurrir juntas (cada elemento en q es "xyz" o "123", nunca "123" Y "xyz"), sigo obteniendo resultados. El resultado es entonces el mismo que el último hilo al que llegó.

He echado un vistazo a la consulta de linq y parece que crea el sql correcto, pero reemplaza a @ p1 AND @ p2 por el mismo valor (último valor).

¿Qué estoy haciendo mal?


Posiblemente un problema variable capturado; intente agregar:

List<string> keys = FillKeys() foreach (string key in keys){ string tmp = key; q = q.Where(c => c.Company.Name.Contains(tmp)); }


se ha corregido en C # 5.0, y el ejemplo anterior en C # 5.0 funciona pero falla en las versiones anteriores de C #.

Pero ten cuidado, no se trata de un bucle for

static void Main() { IEnumerable<char> query = "aaa bbb ccc"; string lettersToRemove = "ab"; Console.WriteLine("/nOK with foreach:"); foreach (var item in lettersToRemove) { query = query.Where(c => c != item); } foreach (char c in query) Console.Write(c); //OK: Console.WriteLine("/nOK with foreach and local temp variable:"); query = "aaa bbb ccc"; foreach (var item in lettersToRemove) { var tmp = item; query = query.Where(c => c != tmp); } foreach (char c in query) Console.Write(c); /* An IndexOutOfRangeException is thrown because: firstly compiler iterates the for loop treating i as an outsite declared variable when the query is finnaly invoked the same variable of i is captured (lettersToRemove[i] equals 3) which generates IndexOutOfRangeException The following program writes aaa ccc instead of writing ccc: Each iteration gets the same variable="C", i (last one frome abc). */ //Console.WriteLine("/nNOK with for loop and without temp variable:"); //query = "aaa bbb ccc"; //for (int i = 0; i < lettersToRemove.Length; i++) //{ // query = query.Where(c => c != lettersToRemove[i]); //} //foreach (char c in query) Console.Write(c); /* OK The solution is to assign the iteration variable to a local variable scoped inside the loop This causes the closure to capture a different variable on each iteration. */ Console.WriteLine("/nOK with for loop and with temp variable:"); query = "aaa bbb ccc"; for (int i = 0; i < lettersToRemove.Length; i++) { var tmp = lettersToRemove[i]; query = query.Where(c => c != tmp); } foreach (char c in query) Console.Write(c); }


Está reutilizando la misma variable ( key ) en su expresión lambda.

Vea mi artículo sobre métodos anónimos para más detalles, y también hay una serie de preguntas SO relacionadas:

La solución simple es copiar la variable primero:

List<string> keys = FillKeys() foreach (string key in keys){ string copy = key; q = q.Where(c => c.Company.Name.Contains(copy)); }