NHibernate Linq提供程序和take()skip(),带急切抓取

NHibernate Linq提供程序和take()skip(),带急切抓取,linq,nhibernate,Linq,Nhibernate,我在NHibernate 3.2和SQLite提供程序中有一个简单的linq查询: var all = (from book in Session.Query<Book>() select book) .Skip(15) .Take(15) .ToList(); 这有效地将结果集限制为15行,而不是我想要的15个实体。skip和take在sql中被转换为限制行的等价项,并且由于您渴望使用联接进行获取,因此您对此无能为力 要获取

我在NHibernate 3.2和SQLite提供程序中有一个简单的linq查询:

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

这有效地将结果集限制为15行,而不是我想要的15个实体。

skip和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();
var all=Session.Query()
.Skip(15)
.Take(15)
.ToList();
var Id=all.Select(b=>b.Id).ToList();
//获取所有书籍的作者,现在所有中的书籍都已初始化作者
Session.Query()
.其中(b=>Id.Contains(b.Id))
.FetchMany(books=>books.Authors)
.List();
不过这有两次往返

更新:一次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();
var subquery=QueryOver.Of()
.Skip(15)
.Take(15)
.选择(b=>b.Id);
var all=Session.QueryOver()
.WithSubquery.WhereProperty(b=>b.Id).In(子查询)
.Fetch(books=>books.Authors)。渴望
.ToList();
var data=session.QueryOver()
.其中(x=>x.薪资>2000)
//.采取(2)
.跳过(2)
.采取(2)
.List();
//如果take在skip之前,则它将跳过最后(提到的数字)行
//如果take在skip之后,那么它将跳过第一行(提到的数字)

听起来像是NHibernate在生成内部联接,而它应该生成左联接。我想,这不是问题所在,因为我每本书至少有一位作者。在foreach循环中获取每本书的作者时,我得到了正确的结果。有趣的是,我确实返回了15行,但只有11个实体。两本书有两位作者,一本书有三位作者。skip和take应该限制返回的实体的数量而不是行的数量,这是对的吗?这种行为看起来确实有点奇怪。我们可以从Linq查询中假设该限制应适用于书籍,但该查询限制了导致书籍数量减少的组合数量。我能看到的唯一修复方法是在FetchMany()之后和Skip()之前放置一个AsEnumerable(),但很难估计这会对性能造成什么影响。这确实有效,但它会加载所有书籍并将结果过滤到内存中。这正是我打算通过引入分页来阻止的。我不知道这种奇怪的行为是由于nHibernate Sqlite驱动程序的问题还是其他原因造成的。我将尝试另一个数据库并发布结果。在思考了这个问题后,我得出了相同的结论,尽管这很遗憾。当指定take(15)并将查询设置为泛型类型Book时,您可能会得到15本书。我试图构造一个sql语句来实现这一点,但想不出解决方案。那么,这将是两个查询。
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();
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();
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