NHibernate 3.0: нет FirstOrDefault () с QueryOver? - PullRequest
29 голосов
/ 29 декабря 2010

Я играю с FluentNHibernate и NH 3.0, используя поставщика LINQ и новый синтаксис QueryOver.

Теперь с помощью QueryOver я хочу получить элемент (называемый результатом) со значением метки времени, максимально приближенным к данному значению, но не более:

 Result precedingOrMatchingResult = Session.QueryOver<Result>().
        Where(r => r.TimeStamp < timeStamp).
        OrderBy(r => r.TimeStamp).Desc.                
        FirstOrDefault(); //get the preceding or matching result, if there is any

Теперь Intellisense говорит мне, что не существует такого понятия, как FirstOrDefault() метод. Я мог бы, конечно, перечислить свой заказанный запрос, а затем использовать LINQ, чтобы получить мой товар. Но это сначала загрузит все элементы в память.

Есть ли альтернатива FirstOrDefault(), или я понял что-то совершенно неправильно?

Ответы [ 5 ]

36 голосов
/ 29 декабря 2010

Теперь я обнаружил, что могу использовать метод расширения Take () в экземпляре IQueryOver и только перечислять в список, например:

Result precedingOrMatchingResult = Session.QueryOver<Result>().
        Where(r => r.TimeStamp < timeStamp).
        OrderBy(r => r.TimeStamp).Desc.   
        Take(1).List(). //enumerate only on element of the sequence!
        FirstOrDefault(); //get the preceding or matching result, if there is any
22 голосов
/ 25 августа 2011
Result precedingOrMatchingResult = Session.QueryOver<Result>()
                                          .Where(r => r.TimeStamp < timeStamp)
                                          .OrderBy(r => r.TimeStamp).Desc
                                          .SingleOrDefault();
12 голосов
/ 30 декабря 2010

NH 3 имеет встроенного поставщика LINQ (запросы переводятся изнутри на HQL / SQL).Вы должны добавить пространство имен NHibernate.Linq, а затем:

Result precedingOrMatchingResult = Session.Query<Result>().
    Where(r => r.TimeStamp < timeStamp).
    OrderByDescending(r => r.TimeStamp).
    FirstOrDefault();
10 голосов
/ 29 декабря 2010

Попробуйте

Result precedingOrMatchingResult = Session.QueryOver<Result>().
        Where(r => r.TimeStamp < timeStamp).
        OrderBy(r => r.TimeStamp).Desc.
        SetFetchSize(1).
        UniqueResult();

UniqueResult вернет единственное значение или ноль, если значение не найдено, что в первую очередь делает First или Default.

Установка размера выборки на 1 может или не может потребоваться, я бы проверил это с помощью профилировщика.

0 голосов
/ 11 апреля 2019

SetFetchSize(1) требуется. Если ваш запрос LINQ возвращает более одного результата, он выдаст исключение NHibernate, используя UniqueResult(), так как он ожидает только один результат, который будет возвращен из запроса.

...