Ленивая загрузка действительно плоха?

Я много слышу о проблемах производительности о ленивой загрузке, независимо от того, в NHibernate, Linq....

проблема в том, что N+1 выбирает. Например, я хочу, чтобы все сообщения и его пользователи, в foreach я ленивые пользователи нагрузки, их мне нужно один выбор для сообщений, плюс N выбор для каждого пользователя.

Отложенная Загрузка:

1 - select ....from post
Н -select ....from user

"хороший" подход - это соединение:

1 - select .....from post inner join user on post.UserId = user.Id

но видеть EF сгенерированный SQL, Я понял, что много данных теряется. Представьте, что все сообщения являются одним и тем же пользователем. Внутреннее соединение принесет все столбцы пользователей для каждой строки post.

в производительности, какой подход лучше?

5 ответов


ленивая загрузка ни хороша, ни плоха. См. это для более длинного объяснения:

когда следует избегать использования функции ленивой загрузки NHibernate?

В общем, ленивая загрузка-хорошее поведение по умолчанию для ORM, но как пользователь ORM вам нужно знать, когда переопределять значение по умолчанию и загружать данные с нетерпением. Профилирование производительности приложения-лучший способ принять решение об использовании ленивой загрузки или ее неиспользовании. Опасаться тратить слишком много усилий на преждевременную оптимизацию.


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


большинство моих приложений включают границу службы (веб-служба, WCF и т. д.), И в этот момент ленивая загрузка в OR/M бессмысленна, а реализация ленивой загрузки в ваших сущностях, которые сидят поверх вашей службы, - это плохая идея (сущности теперь должны знать о службе).


нет плохого и хорошего для ленивой загрузки. Вы должны решить, предпочитаете ли вы загружать ресурсы во время выполнения или во время загрузки приложения. Например-в реальном времени обычно используется буфер, чтобы избежать выделения ресурсов во время выполнения. Это противоположность ленивой загрузки и полезно для программного обеспечения в реальном времени.

ленивая загрузка полезна, если у вас есть приложение, которое работает в течение длительного времени, и вы не хотите выделять ресурсы при запуске.


старый поток, но поиск перевернул его, поэтому я добавляю свои два цента. В дополнение к необходимости знать о потенциальных проблемах производительности, проблема доступа к полям после удаления контекста данных останавливает меня от использования LL сейчас. Если вы вернете экземпляр сущности из метода, в котором был создан и удален контекст данных, как они предназначены для использования, доступ к этим виртуальным полям будет исключением ошибки. Решения для этого должны либо включать поля в запросы (т. е. .Include), никогда не возвращать классы сущностей из слоя данных / службы или сохранять контексты данных живыми намного дольше. Включение полей-лучший вариант, и это так же просто без ленивой загрузки.