Ответ 1
У меня есть интересные результаты тестирования производительности, и я нашел преступника. Я не видел такой информации в любом источнике EF, который я когда-либо читал.
Оказывается, что он равен нулю в базовом классе. Базовый класс должен содержать свойство Id, разделяемое всеми типами конкретных объектов. Этот подход рекомендован многими EF-книгами и довольно хорошо известен. Вы можете найти его здесь, например: Как наилучшим образом реализовать Equals для пользовательских типов?
Более точно, производительность убита операцией unboxing (преобразование объекта в конкретный тип), что заставило его работать так медленно. Когда я прокомментировал эту строку кода, потребовалось 3 секунды для запуска против 90 секунд раньше!
public override bool Equals ( object obj )
{
// This line of code made the code so slow
var entityBase = obj as EntityBase;
...
}
Как я понял, я начал думать о том, что может быть альтернативой этому Равновению. Первая идея заключалась в том, чтобы реализовать IEquatable для EntityBase, но это случилось вовсе не с запуском. Итак, в конечном итоге я решил реализовать IEquatable для каждого конкретного класса сущности в моей модели. У меня их мало, поэтому для меня это небольшое обновление. Вы можете поместить всю функциональность Equal operation (обычно это сравнение объектов 2 объекта) в метод расширения для совместного использования между конкретными классами сущностей и запустить его следующим образом: Equal ((EntityBase) ConcreteEntityClass). Самое интересное, этот IEquatable ускоряет EntitySet.Add 6 раз!
Итак, у меня больше нет проблем с производительностью, тот же код работает для меня менее чем за секунду. Я получил прирост производительности в 180 раз! Потрясающе!
Заключение
- Самый быстрый способ запуска EntitySet.Add - иметь IEquatable для конкретной сущности (0.5 сек)
- Отсутствует IEquatable заставляет его запускать 3 сек.
- Имея Equals (объект obj), который рекомендует большинство источников, он запускает 90 секунд