Я понимаю ответы, говорящие мне, чтобы я упаковывал свои данные, а не загружал всю сущность и т. Д .; и в целом я согласен с таким подходом. Однако в этом сценарии мы выбираем одну сущность - поскольку она поступает из нормализованной базы данных, она предполагает объединение нескольких таблиц.
В этом точном примере ужасный запрос, сгенерированный EF, все еще выполняется менее чем за 0,2 секунды. Если бы я захотел написать запрос, он, вероятно, снова занял бы 1/10. Как это, это определенно достаточно быстро. Размер всей сущности на проводе составляет <6Kb; что, опять же, я считаю достаточно маленьким. </p>
Так что для меня, чтобы группировать эту единственную сущность по нескольким запросам, просто не работает в этом примере. Ясно, что если бы я использовал прямой ADO.NET и веб-сервисы / WCF, у меня не было бы этой проблемы. Во всяком случае, на ответ:
Я уже говорил, что компиляция запроса EF не помогла. Однако, возможно, это связано с тем, что RIA Services применяет условие «Где EntityID = ID» поверх моего исходного запроса и удаляет мой скомпилированный запрос.
Если я просто сделаю это в службе моего домена:
(from e in ctx.Entities
.Include("SubEntity")
.Include("SubEntity.SubEntity")
// and so on, X20...
where e.EntityID == id
select e).FirstOrDefault();
Эта строка кода выполняется почти все время, но SQL работает очень быстро. Просто медленно добраться до SQL Server. Поэтому для меня это означает, что EF требуется много времени для генерации запроса.
Чтобы устранить проблему, я сделал предварительно скомпилированный запрос, который выбирает мою сущность напрямую по ID и материализует ее, а не возвращает IQueryable:
private static Func<DataContext, Guid, Entity> getEntityByEntityID =
CompiledQuery.Compile<DataContext, Guid, Entity>(
(ctx, id) => (from e in ctx.Entities
.Include("SubEntity")
.Include("SubEntity.SubEntity")
// and so on, X20...
where e.EntityID == id
select e).FirstOrDefault());
Затем я предоставляю новую операцию в моей доменной службе для использования скомпилированного запроса:
public Entity GetEntityByEntityID(Guid entityID)
{
return getEntityByEntityID(this.ObjectContext, entityID);
}
Результат: теперь он немного медленнее при первом вызове. Для последующих вызовов операция в среднем составляет около 0,5 секунды для всего вызова службы.