NHibernate висит на ленивый загруженный запрос - PullRequest
0 голосов
/ 14 декабря 2009

Прежде всего, я использую Fluent NHibernate с LinqToNHibernate.

У меня есть запрос на поиск в таблице по тем данным, которые вводил пользователь. Так, например, я делаю что-то вроде этого:

        'build the initial query that we will filter--this is lazy loaded
    Dim results As IEnumerable(Of Customers) = Me.GetCustomers()

    'filter by owner name
    If String.IsNullOrEmpty(OwnerName) = False Then
        results = results.Where(Function(s) s.Name.Contains(OwnerName))            
    End If

    'execute query
    results = results.ToList()

Так что, по сути, я создаю оператор where для оператора sql, если пользователь хочет выполнить поиск по имени. Я использую все ленивые конфигурации в своих сопоставлениях, поэтому запрос не должен извлекать элементы, пока не будет вызван ToList (). Проблема в том, что NHibernate зависает от этого утверждения. Сначала я подумал, что это потому, что в БД было так много записей (около 500 000).

Но я изменил строку, в которой фильтрую результаты, так:

results = SessionFactoryProvider.SessionFactory.CurrentSession.Linq(Of Customer).Where(Function(c) c.Name.Contains(OwnerName))

И это работает очень быстро. Но я не могу понять, почему. Есть идеи?

1 Ответ

0 голосов
/ 15 декабря 2009

В первом случае вы извлекаете все записи и используете Linq-to-objects для фильтрации этого списка.

Во втором случае вы отправляете запрос в базу данных (NHibernate.Linq преобразует ваше выражение в предложение SQL WHERE).

Теперь я не знаю, каков тип возврата GetCustomers, но, поскольку вы сохраняете его в IEnumerable (Of Customer), .NET не может узнать о соответствующем поставщике. Если код GetCustomers похож на:

Return CurrentSession.Linq(Of Customer)

... Тогда проблема в том преобразовании. Просто измените первую строку на:

Dim results As IQueryable(Of Customers) = Me.GetCustomers()
...