2012-04-10 18 views
127

¿Alguna idea sobre por qué esto podría estarse rompiendo?Nueva transacción no está permitida porque hay otros subprocesos ejecutándose en la sesión LINQ To Entity

foreach (var p in pp) 
{ 
    ProjectFiles projectFile = (ProjectFiles)p; 
    projectFile.Status = Constants.ProjectFiles_ERROR; 
    projectFile.DateLastUpdated = DateTime.Now; 
    context.SaveChanges(); 
} 

leí que la solución del problema, es para recuperar los resultados de una sola vez antes de que el bucle foreach.

¿Pero no hice eso? "pp" es la colección de resultados en mi caso

+10

¿Es 'pp' el resultado de una consulta linq? Si es así, es posible que deba hacer un 'ToList()' para desconectarlo de la base de datos antes de ejecutar el ciclo. – SouthShoreAK

+0

Sí lo es. Ok, intentaré eso. Gracias –

+2

llamada guardar cambios fuera del bucle – Mohsin

Respuesta

321

La variable pp no es una colección de objetos, es un enumerador que puede devolver objetos. Mientras usa el enumerador, la fuente debe permanecer abierta.

Utilice el método ToList para convertir el enumerador en una colección. Eso leerá todos los elementos del enumerador y cerrará la conexión a la fuente, para que pueda usar la conexión para otras cosas.

foreach (var p in pp.ToList()) 
+14

Dios te bendiga @Guffa !!! +1 –

+2

¡Genial! También funciona con pp.ToArray() –

+2

Ricardo, funciona siempre que no sea IQueryable –

7

Lo que sucede es que usted está utilizando una conexión de SQL para iterar sobre una colección de entidades db, a continuación, utilizando otra conexión para guardar los cambios. Esto sucede porque tus clases están básicamente "casadas" con una instancia de tu conexión de db y no pueden ser cambiadas por otra.

Una forma de evitar esto es llamar a .ToList() en su colección antes de iterarlo.

Y mientras lo hace, llame al context.SaveChages() una sola vez después de que el bucle salga para acelerar el código.

Cuestiones relacionadas