2015-12-07 3 views
0

This представляет собой простой пример выбора n + 1 проблемы в ORM в pht, но идея должна быть одинаковой в других ORM других языков.решение для выбора n + 1 автоматически

Типичным решением является использование загружаемой загрузки, чтобы уменьшить ее до 1 запроса, что, по моему мнению, не очень сложно, но OTOH, это довольно хрупкий, потому что последний рефакторинг потребует от разработчиков изменения двух мест, в противном случае эта проблема выбора n + 1 возникает снова.

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

Это, вероятно, слишком много, чтобы попросить ORM реализовать с использованием интерпретируемых языков, таких как ruby, php и т. Д. Однако ни один из них (NHibernate) и C# (инфраструктура Entity) не делает этого анализа пути AFAIK. Почему это?

ответ

0

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

кстати здесь вы можете найти старый и связанный с этим вопрос, как ваш: What is SELECT N+1?

, как я прокомментировал ниже, может быть метод, который вы вызываете, чтобы добавить все необходимое Include, так что, когда вы добавляете новое навигационное свойство/коллекцию, которое вы только что должны запомнить, этот ответ показывает вам, что con cept: https://stackoverflow.com/a/14520939/1716620

+0

Да, я могу использовать 'Include' для решения проблемы с выбором n + 1, но все, что я помещаю в' Include', должно соответствовать использованию ниже. Например, в более позднем рефакторинге я добавил еще один элемент в представлении, но забудьте обновить 'Include', я снова буду страдать от этой проблемы с выбором n + 1. Я понимаю эту концепцию n + 1, но мне любопытно, почему она не может быть автоматически решена компилятором. –

+0

компилятор не может знать, как вы хотите обрабатывать свои сущности, вам решать, какие типы связанных объектов загружаются с нетерпением или ленивыми, когда вы создаете запрос linq, вы просто создаете представление IQuearable запроса и он не решается во время компиляции, но во время выполнения компилятор просто проверяет, удовлетворены ли общие ограничения реализации, но только во время выполнения запрос решается и переводится на SQL или какая-либо идиома, которую необходимо преобразовать. в любом случае вы можете реализовать свою логику для добавления включает в себя до перечисления вашего IQuerable (так, прежде чем генерировать SQL). –

+0

Для этого компилятор должен знать об ORM. Возможно, вы могли бы сделать что-то вроде того, что вы думаете об использовании Roslyn в C#. –