Tengo> 67000 registros llegando a mi sistema desde otra fuente. Después de aplicar las reglas comerciales a esos registros, debo almacenarlos en la base de datos. Yo uso siguiente código para hacerlo:Entity Framework (EF) OutOfMemoryException
using (var context = new MyEntities())
{
var importDataInfo = context.ImportDataInfoes.First(x => x.ID == importId);
importedRecords.ForEach(importDataInfo.ValuationEventFulls.Add);
context.SaveChanges();
}
Después de ejecutar el código que estoy recibiendo error de seguimiento (OutOfMemoryException)
Error in executing code|Exception of type 'System.OutOfMemoryException' was thrown.* at System.Data.Mapping.Update.Internal.KeyManager.<WalkGraph>d__5.MoveNext()
at System.Data.Mapping.Update.Internal.KeyManager.GetPrincipalValue(PropagatorResult result)
at System.Data.Mapping.Update.Internal.UpdateCompiler.GenerateValueExpression(EdmProperty property, PropagatorResult value)
at System.Data.Mapping.Update.Internal.UpdateCompiler.BuildSetClauses(DbExpressionBinding target, PropagatorResult row, PropagatorResult originalRow, TableChangeProcessor processor, Boolean insertMode, Dictionary`2& outputIdentifiers, DbExpression& returning, Boolean& rowMustBeTouched)
at System.Data.Mapping.Update.Internal.UpdateCompiler.BuildInsertCommand(PropagatorResult newRow, TableChangeProcessor processor)
at System.Data.Mapping.Update.Internal.TableChangeProcessor.CompileCommands(ChangeNode changeNode, UpdateCompiler compiler)
at System.Data.Mapping.Update.Internal.UpdateTranslator.<ProduceDynamicCommands>d__0.MoveNext()
at System.Linq.Enumerable.<ConcatIterator>d__71`1.MoveNext()
at System.Data.Mapping.Update.Internal.UpdateCommandOrderer..ctor(IEnumerable`1 commands, UpdateTranslator translator)
at System.Data.Mapping.Update.Internal.UpdateTranslator.ProduceCommands()
at System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter)
at System.Data.EntityClient.EntityAdapter.Update(IEntityStateManager entityCache)
at System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options)
estoy usando EF 4.0.
Mi pregunta es ¿existe una limitación en el número de registros para guardar? ¿Cuál es la mejor práctica para guardar una gran cantidad de registros (guárdelos en fragmentos? ¿Qué pasa con las transacciones?).
Gracias a todos de antemano.
Gracias por su respuesta. - Sí, cambié mi código para probar si funciona con fragmentos de registros y, de hecho, funciona, pero mi pregunta es: no he leído nada sobre la limitación del número de registros en SaveChanges() en EF. ¿Has tenido noticias de MS sobre esta restricción? –
@Vlad Bezden, la restricción no está conectada específicamente con EF, es solo parte de trabajar con la tecnología .NET. Cuando registra ETL 67K, es probable que tenga 200k + objetos en la memoria. Tienes los 67k registros originales, tienes los 67k objetos EF, y cada uno crea una cantidad de entidades de seguimiento de estado dentro del contexto para cada objeto, así que ahí ya están 67k + 67k + 67k, no me sorprendería que un par de otros objetos auxiliares se crean a lo largo del camino también. EF trabaja en un patrón de consulta diferida, no hace un trabajo real hasta que no llame a SaveChanges, es por eso que ocurre el OOM. –
Tengo un problema similar. No está claro cómo se debe cambiar el fragmento. Sería bueno ver como una actualización de la pregunta original. Tengo el código existente donde hay .Add dentro de foreach loop y SaveChanges inmediatamente después del ciclo. No está claro si incluye SaveChanges en un bucle, ¿siempre se borra lo que se agregó a través de.Agregue – MicMit