2012-04-14 14 views

Respuesta

7

Hay varias cosas que están mal en el enfoque de bucle, el ser más importante - no se puede quitar artículos de la colección que está iterando actualmente con foreach - obtendrá una excepción.

Dado que su colección principal es List<T>, debe utilizar el método RemoveAll que toma un predicado. También debe simplificar su consulta de esta manera:

AllItems.RemoveAll(item => !db.tblStoreItems.Any(i => i.ID == item.ItemID)); 
+1

¡Hermoso gracias! –

9

No lo creo. Si elimina un elemento de la lista en la que está iterando, los resultados serán incorrectos.

Lo mejor es utilizar una vieja moda para - bucle en sentido inverso

using(var db = new MainContext()) 
{ 
    for(int x = AllItems.Count - 1; x >= 0; x--) 
    { 
     var item = AllItems[x]; 
     if (!db.tblStoreItems.Where(i => i.ID == item.ItemID).Any()) 
     { 
      AllItems.RemoveAt(x); 
     } 
    } 
} 
+0

Awesome thanks! –

+0

Se están eliminando elementos de la matriz y, paralelamente, se está produciendo un bucle para la cantidad original de elementos. Finalmente, se bloqueará en 'Índice fuera de rango'. – Pankaj

1

que está mal (el enfoque de la OP) como acertadamente sugerido por Steve (camino de Steve es probablemente el mejor en términos de rendimiento),

Prefiero almacenar el 'those to be removed' en una lista separada, entonces puede hacer, por ejemplo

AllItems = AllItems.Except(Items2Remove); 

Ese no es el mejor modo de rendimiento, pero para mí hace las cosas más limpias - también se puede combinar con LINQ enumerar - por ejemplo, hacer IEnumerable de la lista de registros, etc.

espero que esta ayuda EDIT: sólo para aclarar según la respuesta de Steve

+0

@Steve tal vez lo puse 'mal' :) - el tuyo es perfecto - quise decir 'su enfoque'. Simplemente prefiero ir 'dos ​​veces', el tuyo es más eficiente y funciona perfecto. – NSGaga

Cuestiones relacionadas