... Nuestra prueba consistió en agregar una instancia única, no inicializada de la clase a la base de datos. Usando DbContext.Add ...
Quizás quiso asegurarse de que se crea el Código-Primer modelo y se carga en la memoria antes de que ha llamado Add
? Me refiero a lo siguiente: Si se utiliza un código de prueba como esta ...
using (var context = new MyContext())
{
var myHugeBusinessObject = CreateItSomeHow();
context.HugeBusinessObjects.Add(myHugeBusinessObject);
context.SaveChanges();
}
... y es la primera vez que se utiliza el contexto de la aplicación de prueba Add
en realidad pasado algún tiempo para construir la Modelo EF en memoria antes de que comience a agregar el objeto al contexto.
Puede separar estos dos pasos, simplemente añadiendo un método ficticio antes de llamar Add
, por ejemplo, algo como:
context.HugeBusinessObjects.Count();
He construido una prueba:
public class MyClass
{
public int Id { get; set; }
public string P1 { get; set; }
// ... P2 to P49
public string P50 { get; set; }
public MyClass Child1 { get; set; }
// ... Child1 to Child26
public MyClass Child27 { get; set; }
}
Con esta creé un objeto:
var my = new MyClass();
MyClass child = my;
for (int i = 0; i < 100; i++)
{
child.Child1 = new MyClass();
child = child.Child1;
}
child = my;
for (int i = 0; i < 100; i++)
{
child.Child2 = new MyClass();
child = child.Child2;
}
// and so on up to Child27
Así que este gráfico de objetos tiene 2700 objetos secundarios con ingenio h 50 propiedades escalares cada una. Entonces probé este código:
using (var context = new MyContext())
{
var my = CreateWithTheCodeAbove();
context.MyClassSet.Count();
context.MyClassSet.Add(my);
context.SaveChanges();
}
...Count()
(= la construcción del modelo EF) necesita aproximadamente 25 segundos. Add
necesita 1 segundo. (Cambiar 100 a 1000 en los bucles de arriba (teniendo entonces 27000 objetos en el gráfico) aumenta el tiempo para Add
de forma casi lineal a 9-10 segundos.) Este resultado es independiente de la configuración AutoDetectChangesEnabled
a true
o false
.)
El siguiente resultado interesante: Si agrego 20 propiedades de navegación más (Child28
Child47
a) a MyClass
el tiempo pasado con la construcción del modelo (Count()
en el código de ejemplo) explota a 140 segundos. La duración de Add
solo aumenta linealmente con las propiedades adicionales.
Entonces, mi hipótesis es: en realidad no está midiendo el tiempo para agregar su objeto comercial al contexto, sino el momento en que EF necesita construir el modelo EF en la memoria. El tiempo para construir el modelo parece crecer exponencialmente con la complejidad del modelo: número de propiedades de navegación en una clase y quizás también el número de diferentes clases involucradas.
Para separar estos pasos, realice una prueba con alguna llamada ficticia como se sugirió anteriormente. Si ya tienes esta separación ... omg, olvida esta publicación.
¿Has mirado el SQL que está generando en Sql Profiler? A veces se puede deducir mucho sobre lo que EF está tratando de hacer mirando el sql. En mi opinión, salvar 60 clases relacionadas a la base de datos debe ser una operación secundaria de 1 segundo para EF. – automagic
No lo habíamos probado, porque sabíamos que solo estaba llegando a la base de datos al final y todo el procesamiento estaba teniendo lugar dentro de EF. El rastro es muy grande ... No estoy muy seguro de lo que debería estar buscando. – dythim
Intente configurar 'dbContext.Configuration.AutoDetectChangesEnabled = false;' cuando cree el contexto y mida de nuevo. Como dices 'Add' es lento (y no' SaveChanges', ¿no?) Sospecho que la detección automática de cambios/creación de instantáneas hace que las cosas vayan más despacio. – Slauma