Ответ 1
Я могу подтвердить это медленное поведение, и я также нашел основную причину. Я сделал небольшой тест со следующей моделью...
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 строк в сущности), исходный код:
- > время = 3,4 с
Итак, да, очевидно, имеет значение число свойств.
Тест 5
Добавьте следующую строку перед циклом (модель снова со всеми 50 свойствами):
context.Configuration.AutoDetectChangesEnabled = false;
- > время = 1,4 сек
Тест 6
Снова с AutoDetectChangesEnabled = false
, но с 5 свойствами:
- > время = 1,3 с
Таким образом, без отслеживания изменений количество свойств больше не имеет значения.
Заключение
На данный момент большую часть времени, по-видимому, тратится на получение моментального снимка свойств прикрепленных объектов механизмом отслеживания изменений. Если вам не нужно отключать отслеживание изменений для фрагмента кода. (Я думаю, что в вашем коде вам действительно не нужно отслеживать изменения, потому что, установив состояние entitiy на Modified
, вы в основном помечаете все свойства как измененные в любом случае. Таким образом, все столбцы отправляются в базу данных в инструкции обновления.)
Edit
Время тестирования выше в режиме отладки. Но режим Release не имеет большого значения (например: Test 1 = 28,7 с, тест 5 = 0,9 сек).