Недавно я перенес мою модель объекта из ObjectContext, используя 4.1 в DbContext, используя 5.0. Я начинаю сожалеть об этом, потому что замечаю очень низкую производительность по запросу, используя DbContext vs ObjectContext. Здесь тестовый сценарий:
Оба контекста используют одну и ту же базу данных с примерно 600 таблицами. LazyLoading и ProxyCreation отключены для обоих (не показаны в примере кода). Оба имеют предварительно сгенерированные представления.
Тест сначала делает 1 вызов для загрузки рабочего пространства метаданных. Затем в цикле for, который выполняется 100 раз, я обновляю контекст и делаю один вызов, который принимает первый 10. (Я создаю контекст внутри цикла for, потому что это имитирует использование в службе WCF, что создаст контекст каждый раз)
for (int i = 0; i < 100; i++)
{
using (MyEntities db = new MyEntities())
{
var a = db.MyObject.Take(10).ToList();
}
}
Когда я запускаю это с ObjectContext, он занимает около 4,5 секунд. Когда я запускаю его с помощью DbContext, это занимает около 17 секунд. Я профилировал это с использованием профилировщика производительности RedGate. Для DbContext кажется, что основным виновником является метод UpdateEntitySetMappings. Это вызывается для каждого запроса и, как представляется, извлекает метаданные и просматривает каждый элемент в OSpace. AsNoTracking не помогло.
EDIT: Чтобы дать более подробную информацию, проблема связана с созданием\инициализацией DbSet и ObjectSet, а не с фактическим запросом. Когда я делаю вызов с ObjectContext, для создания ObjectSet требуется в среднем 42 мс. Когда я звоню с DbContext, для создания внутреннего dbset требуется около 140 мс. Оба объекта ObjectSet и DbSet выполняют некоторые сопоставления сопоставления сущностей из метаданных. Я заметил, что DbSet делает это для ВСЕХ типов в рабочей области, а ObjectSet - нет. Я предполагаю (не пробовал), что модель с меньшим количеством таблиц отличается от разницы в производительности.