Entity Framework, настройка производительности - PullRequest
1 голос
/ 08 октября 2011

У меня есть сущность "Идеи", у которой есть коллекция дочерних сущностей "ChildIdeas". Мне нужно загрузить список идей и количество «ChildIdeas» (только считать!). Я могу сделать:

нетерпеливая загрузка

from i in _dataContext.Ideas.Include("ChildIdeas") ...

преимущества: все необходимые данные получены одним запросом; Недостатки: загрузка ненужных данных. Мне нужен только счет ChildIdeas, а не полный список ChildIdeas

Явная загрузка

from i in _dataContext.Ideas ...

idea.ChildIdeas.Loading()

преимущества: нет; недостатки: много запросов (ideas.count + 1) вместо одного, загрузка ненужных данных

Независимые запросы

from i in _dataContext.Ideas ...

_repository.GetCountChildIdeas(idea.ID);

преимущества: загружать только необходимые данные; недостатки: много запросов (ideas.count + 1) вместо одного

все 3 типа имеют недостатки. Может быть, существует какой-либо способ загрузить только необходимые данные? Если да - что это, если нет - какой путь лучше для этого случая?

[ADDED] после нагрузочного тестирования (для 1 пользователя) я получил Page Load (в секундах): Стремительные детские идеи - 1,31 сек. явные детские идеи - 1,19 сек внешние запросы - 1,14 с

Итак, нетерпеливый способ для моего случая - худший ... Почему даже явный способ лучше?

1 Ответ

2 голосов
/ 08 октября 2011

Вы должны использовать проекцию. Count дочерних идей не является частью персистентной Idea сущности, поэтому создайте новый неотображаемый тип, содержащий все свойства из Idea сущности и Count свойства.

public class IdeaProjection
{
    public int Id { get; set; }
    // Other properties
    public int Count { get; set; }
}

Теперь вы можете использовать простой проекционный запрос для получения всего за один запрос без загрузки каких-либо дополнительных данных:

var query = from x in context.Ideas
            where ...
            select new IdeaProjection
                {
                    Id = x.Id,
                    // Mapped other properties
                    Count = x.ChildIdeas.Count()
                };

Недостатком является то, что IdeaProjection не является сущностью, и если вы также хотите использовать его для обновлений, вы должны преобразовать его обратно в Idea и сообщить EF об изменениях. С точки зрения производительности лучше всего использовать EF без возврата к SQL или хранимым процедурам.

...