2012-03-15 27 views
10

Tôi đã có truy vấn LINQ đơn giản này trong NHibernate 3.2 và cung cấp SQLite:cung cấp NHibernate LINQ và mất() skip() với háo hức lấy

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

Truy vấn này trả về đúng 15 đơn vị, nhưng khi tôi cố gắng mong muốn tải một bộ sưu tập phụ thuộc với FetchMany như thế này:

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

Tôi chỉ nhận được 11 thực thể. Đây có phải là một lỗi hoặc một cái gì đó tôi đang mất tích?

Dưới đây là kết quả truy vấn 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 */ 

này có hiệu quả hạn chế kết quả thiết lập để 15 hàng và không 15 đơn vị như tôi dự định.

+0

Âm thanh như NHibernate đang tạo ra một kết nối bên trong khi cần tạo một kết nối bên trái. Tôi muốn có một cái nhìn thêm vào các ánh xạ cho các tác giả bất động sản. –

+0

Tôi đoán, đây không phải là vấn đề bởi vì tôi có ít nhất một tác giả cho mỗi cuốn sách. Và khi tìm nạp các tác giả trong vòng lặp foreach cho mỗi cuốn sách, tôi nhận được kết quả chính xác. – zszep

+0

Điều thú vị là, tôi nhận được 15 hàng trả lại, nhưng chỉ có 11 thực thể. Hai cuốn sách có hai tác giả và một cuốn sách có ba tác giả. Tôi có chính xác rằng bỏ qua và lấy nên hạn chế số lượng thực thể trả lại và không phải hàng? – zszep

Trả lời

12

bỏ qua và thực hiện được dịch sang tương đương trong sql giới hạn trên hàng và vì bạn đang háo hức tìm nạp với tham gia không có nhiều bạn có thể làm gì về nó.

để háo hức lấy 15 cuốn sách đầu tiên bạn cần phải:

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(); 

này có 2 roundtrips dù

Cập nhật: một khứ hồi với QueryOver, có lẽ bạn có thể dịch thành 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

Sau khi suy nghĩ về vấn đề này, tôi đã đi đến cùng một kết luận, mặc dù đó là một điều đáng tiếc. Người ta sẽ mong đợi để có được 15 cuốn sách khi chỉ định lấy (15) và thiết lập các truy vấn để được của loại chung Sách. Tôi đã cố gắng để xây dựng một câu lệnh sql mà sẽ làm điều này nhưng không thể nghĩ ra một giải pháp. Vì vậy, nó sẽ là hai truy vấn, sau đó. – zszep

0
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 
Các vấn đề liên quan