... Нашим тестом было добавление одного неинициализированного экземпляра класса в базу данных.Использование DbContext.Add ...
Удалось ли вам убедиться, что ваша модель Code-First создана и загружена в память до , которую вы называли Add
?Я имею в виду следующее: если вы используете такой тестовый код ...
using (var context = new MyContext())
{
var myHugeBusinessObject = CreateItSomeHow();
context.HugeBusinessObjects.Add(myHugeBusinessObject);
context.SaveChanges();
}
... и вы впервые используете контекст в своем тестовом приложении Add
фактически потратит некотороевремя построить модель EF в памяти, прежде чем она начнет добавлять объект в контекст.
Вы можете разделить эти два шага, просто добавив фиктивный метод перед вызовом Add
, например, что-то вроде:
context.HugeBusinessObjects.Count();
Я построил тест:
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; }
}
С этим я создал объект:
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
Таким образом, этот граф объектов имеет 2700 дочерних объектов с 50 скалярамисвойства каждого.Затем я проверил этот код:
using (var context = new MyContext())
{
var my = CreateWithTheCodeAbove();
context.MyClassSet.Count();
context.MyClassSet.Add(my);
context.SaveChanges();
}
...Count()
(= построение модели EF) требует примерно 25 секунд .Add
нужно 1 секунда .(Изменение от 100 до 1000 в вышеприведенных циклах (имея затем 27000 объектов на графике) увеличивает время для Add
почти линейно до 9-10 секунд.) Этот результат не зависит от установки AutoDetectChangesEnabled
в true
или false
.)
Следующий интересный результат: если я добавлю еще 20 свойств навигации (от Child28
до Child47
) к MyClass
времени, потраченному на построение модели (Count()
в примере кода)взрывается до 140 секунд .Продолжительность Add
увеличивается только линейно с дополнительными свойствами.
Итак, моя гипотеза такова: вы на самом деле не измеряете время для добавления вашего бизнес-объекта в контекст, а время, которое необходимо EF дляпостроить модель EF в памяти.Время построения модели, по-видимому, растет в геометрической прогрессии в зависимости от сложности модели: количества свойств навигации в классе и, возможно, также числа различных участвующих классов.
Чтобы разделить эти этапы, проведите тестирование с некоторымификтивный звонок, как предложено выше.Если у вас уже есть это разделение ... о боже, забудьте этот пост.