Как избежать проблемы n + 1 с SubSonic? - PullRequest
1 голос
/ 12 января 2009

У Ayende есть сообщение в блоге , подробно описывающее, как бороться с проблемой "n + 1" в nHibernate. По сути, проблема заключается в следующем:

Предположим, у вас есть две таблицы: «BlogPosts» и «Комментарии» с отношением «один ко многим» между ними (т.е. каждый BlogPost может иметь несколько комментариев). Теперь предположим, что вы хотите выполнить следующий вложенный цикл:

foreach (BlogPost post in blogposts)
{
    foreach (Comment comment in post.Comments)
    {
        // Do something
    }
}

Из того, что я понимаю, классы, которые генерирует SubSonic, по умолчанию являются lazyload (я не хочу отключать это полностью, потому что это полезно в большинстве случаев, только не этот). Это означает, что каждый раз, когда выполняется внутренний цикл (т. Е. При обращении к post.Comments), в базу данных необходимо отправлять отдельный запрос для получения комментариев.

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

Есть ли способ борьбы с этой проблемой в SubSonic в настоящее время?

Ответы [ 3 ]

2 голосов
/ 12 января 2009

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

1 голос
/ 16 января 2009

Я думаю, что вам следует создать частичный метод класса, который получит все комментарии. Не так чисто, но должно работать.

0 голосов
/ 04 апреля 2009

Я тоже использую частичные классы и загружаю связанные классы таблиц, например:

Partial Public Class Book

    Private _Author as Database.Author 
    Property Author() as Database.Author
      Get
         If _Author is nothing then
           ' Load the author class here.
         End if
         return _Author
      End get
      Set
         '....
      End Set
    End Property

End Class
...