Провайдер NHibernate Linq и take () skip () с активной загрузкой - PullRequest
11 голосов
/ 16 марта 2012

У меня есть простой запрос linq в NHibernate 3.2 и SQLite провайдере:

var all = (from book in Session.Query<Book>() select book)
    .Skip(15)
    .Take(15)                
    .ToList();

Этот запрос корректно возвращает 15 сущностей, но когда я пытаюсь загрузить зависимую коллекцию с помощью FetchMany следующим образом:

var all = (from book in Session.Query<Book>() select book)
    .FetchMany(books => books.Authors)
    .Skip(15)
    .Take(15)                
    .ToList();

Я получил только 11 возвращенных объектов. Это ошибка или я что-то упускаю?

Вот результирующий SQL-запрос

select
     book0_.Id as Id2_0_,
     author2_.Id as Id0_1_,
     book0_.Title as Title2_0_,
     book0_.Sort as Sort2_0_,
     book0_.TimeStamp as TimeStamp2_0_,
     book0_.PubDate as PubDate2_0_,
     book0_.Series_Index as Series6_2_0_,
     book0_.Author_Sort as Author7_2_0_,
     book0_.Isbn as Isbn2_0_,
     book0_.Lccn as Lccn2_0_,
     book0_.Path as Path2_0_,
     book0_.Flags as Flags2_0_,
     book0_.Uuid as Uuid2_0_,
     book0_.Has_Cover as Has13_2_0_,
     book0_.Last_Modified as Last14_2_0_,
     author2_.Name as Name0_1_,
     author2_.Sort as Sort0_1_,
     author2_.Link as Link0_1_,
     authors1_.book as book0__,
     authors1_.author as author0__
from 
    books book0_ 
  left outer join 
    books_authors_link authors1_ on book0_.Id=authors1_.book left outer join authors author2_ 
  on authors1_.author=author2_.Id
order by book0_.Id asc
limit 15 /* @p0 */ offset 0 /* @p1 */

Это эффективно ограничивает набор результатов 15 строками, а не 15 объектами, как я намеревался.

Ответы [ 2 ]

13 голосов
/ 16 марта 2012

skip and take переводятся в эквиваленты в sql, которые ограничивают количество строк, и, поскольку вы стремитесь к поиску с помощью объединений, вы ничего не можете с этим поделать.

чтобы получить первые 15 книгнужно:

var all = Session.Query<Book>()
    .Skip(15)
    .Take(15)                
    .ToList();

var ids = all.Select(b => b.Id).ToList();

// fetch all Authors of the books, now the books in all have initialized Authors
Session.Query<Book>()
    .Where(b => ids.Contains(b.Id))
    .FetchMany(books => books.Authors)
    .List();

это имеет 2 раунда, хотя

Обновление: один тур с QueryOver, возможно, вы можете перевести на Linq

var subquery = QueryOver.Of<Book>()
    .Skip(15)
    .Take(15)
    .Select(b => b.Id);

var all = Session.QueryOver<Book>()
    .WithSubquery.WhereProperty(b => b.Id).In(subquery)
    .Fetch(books => books.Authors).Eager
    .ToList();
0 голосов
/ 11 марта 2014
var data = session.QueryOver<EmployeeDetails>()
                                  .Where(x => x.Salary > 2000)
                                  //.Take(2)
                                  .Skip(2)
                                  .Take(2)
                                  .List();
                //if take is before skip then it will skip the last (mentioned digits) rows
                //if take is after skip then it will skip the first (mentioned digits) rows
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...