I've got this simple linq query in NHibernate 3.2 and SQLite provider:
var all = (from book in Session.Query<Book>() select book)
.Skip(15)
.Take(15)
.ToList();
This query returns correctly 15 entities, but when I try to eager load a dependent collection with FetchMany like this:
var all = (from book in Session.Query<Book>() select book)
.FetchMany(books => books.Authors)
.Skip(15)
.Take(15)
.ToList();
I get only 11 entities returned. Is this a bug or something I'm missing?
Here is the resulting SQL query
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 */
This effectively limits the result set to 15 rows and not 15 entities as I intended to.
skip and take are translated to the equivalents in sql which limit on rows and since you are eager fetching with joins there isn't much you can do about it.
to eager fetch the first 15 books you need to:
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();
this has 2 roundtrips though
Update: one roundtrip with QueryOver, maybe you can translate into 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();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With