Я могу подтвердить это медленное поведение, и я также нашел основную причину.Я провел небольшой тест со следующей моделью ...
public class MyClass
{
public int Id { get; set; }
public string P1 { get; set; }
// ... properties P2 to P49, all of type string
public string P50 { get; set; }
}
public class MyContext : DbContext
{
public DbSet<MyClass> MyClassSet { get; set; }
}
... и этой тестовой программой ...
using (var context = new MyContext())
{
var list = new List<MyClass>();
for (int i = 0; i < 1000; i++)
{
var m = new MyClass()
{
Id = i+1,
P1 = "Some text ....................................",
// ... initialize P2 to P49, all with the same text
P50 = "Some text ...................................."
}
list.Add(m);
}
Stopwatch watch = new Stopwatch();
watch.Start();
foreach (var entity in list)
{
context.Set<MyClass>().Attach(entity);
context.Entry(entity).State = System.Data.EntityState.Modified;
}
watch.Stop();
long time = watch.ElapsedMilliseconds;
}
Тест 1
Точно код выше:
-> время = 29,2 сек
Тест 2
Закомментируйте строку ...
//context.Entry(entity).State = System.Data.EntityState.Modified;
-> время = 15,3 с
Тест 3
Закомментируйте строку ...
//context.Set<MyClass>().Attach(entity);
-> время = 57,3 сек
Этот результат очень странный, потому что я ожидал, что вызывать Attach
не нужно, потому что изменение состояния все равно происходит.
Тест 4
Удалить свойства P6 - P50 (таким образом, у нас есть только 5 строк в сущности), оригинальный код:
-> time= 3,4 с
Итак, да, очевидно, что количество свойств сильно имеет значение.
Тест 5
Добавьте следующую строку перед циклом (модель снова со всеми 50 свойствами):
context.Configuration.AutoDetectChangesEnabled = false;
-> time =1,4 сек
Тест 6
Опять с AutoDetectChangesEnabled = false
, но только с 5 свойствами:
-> время = 1,3 с
Таким образом, без отслеживания изменений количество свойств уже не имеет большого значения.
Заключение
Похоже, что большая часть времени уходит на создание снимка свойств прикрепленного объекта с помощью механизма отслеживания изменений. Если вы нене нужно отключать отслеживание изменений для вашего кода.(Я предполагаю, что в вашем коде вам действительно не нужно отслеживать изменения, потому что, устанавливая состояние полномочий на Modified
, вы в основном помечаете все свойства как измененные в любом случае. Так что все столбцы отправляютсяв базу данных в операторе обновления.)
Редактировать
Время тестирования, указанное выше, находится в режиме отладки.Но режим Release не имеет большого значения (например: тест 1 = 28,7 с, тест 5 = 0,9 с).