Pregunta

¿Alguien tiene alguna buena información sobre el uso del método .SaveChanges ()?

Estoy experimentando una variedad de problemas al intentar usar el método .SaveChanges () en mi objeto de contexto de datos. Estoy tomando datos de una fuente de datos existente, creando los objetos EntityFramework / DataService apropiados, rellenando esos objetos creados con datos, agregando esos objetos al contexto y luego guardando esos datos llamando a .SaveChanges.

Los escenarios que se me ocurren (y los problemas asociados con ellos) son como tales ... En cada escenario tengo un bucle foreach que toma datos de filas en una DataTable y genera los objetos, adjuntándolos a el contexto a medida que avanzan. (nota: tres objetos, un '' miembro '' y dos '' direcciones '' que se adjuntan a través de una llamada de SetLink), básicamente, esta es una herramienta de conversión para tomar datos de un almacén de datos y masajearlos en un almacén de datos expuesto por Data Servicios.

  • Llame .SaveChanges () sin ningún parámetro una vez al final del bucle foreach (es decir, fuera del bucle)
    • Error de OutOfMemory alrededor de 1/3 del camino (30,000 de 90,000 guardados) - aunque no estoy seguro de cómo sucede esto, ya que cada elemento guardado es una llamada SQL separada a la base de datos, ¿qué hay para quedarse sin memoria?
  • Llamar .SaveChanges () sin ningún parámetro una vez por ciclo
    • Esto funciona, pero lleva absolutamente para siempre (8 horas por 90,000 salvados)
  • Llame .SaveChanges (SaveChangesOption.Batch) una vez al final del bucle foreach
    • Mismo error de OutOfMemory, pero sin guardar en la base de datos
  • Llamar .SaveChanges (SaveChangesOption.Batch) una vez por ciclo
    • error 404 no encontrado
  • Llame .SaveChanges (SaveChangesOption.Batch) una vez por cada 10 bucles
    • 400 Error de solicitud incorrecta (ocasionalmente)
    • OutOfMemory después de varias iteraciones
  • Varios intentos aleatorios para crear el contexto una vez por ciclo, o tenerlo como una variable al comienzo del ciclo o tenerlo como una variable miembro privada que esté disponible.
    • Resultados diferentes, incapaz de cuantificar, ninguno realmente tan bueno

¿Cuál es el método preferido para llamar a .SaveChanges () desde un objeto de cliente cuando se realiza una carga de datos grande como esta? ¿Hay algo que no entiendo sobre cómo funciona .SaveChanges ()? ¿Alguien puede proporcionar más detalles sobre cómo una vez debería utilizar esta función y cuáles (si las hay) son las limitaciones para guardar datos a través de los servicios de datos? ¿Existen algunas prácticas recomendadas en torno a la llamada al método .SaveChanges ()? ¿Existe alguna documentación particularmente buena sobre la llamada al método .SaveChanges ()?

¿Fue útil?

Solución

No tengo mucha experiencia en el uso de EntityFramework (solo un experimento aleatorio), ¿has intentado llamar a .SaveChanges () cada n iteraciones?

Me refiero a algo como esto:

int i = 0;
foreach (var item in collection)
{
    // do something with your data
    if ((i++ % 10) == 0)
        context.SaveChanges();
}
context.SaveChanges();

Sé que es feo, pero es la primera solución posible que se me ocurrió.

Otros consejos

Estoy usando EntityFramework en un proyecto pequeño también, así que también estoy muy interesado en la pregunta. Dos preguntas rápidas:    ¿Has intentado desactivar el almacenamiento en caché de los objetos de datos en el contexto de datos?    ¿Ha intentado cerrar el contexto de datos y ha creado uno nuevo durante el ciclo para liberar memoria?

Saludos

Kenneth

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top