2010-08-28 154 views
1

在我的ASP.NET Web应用程序中,我使用NHibernate来坚持我的“用户”-Instances,其中每个人都有一个“条目” - 集合。这是一个典型的一对多映射,它工作得很好。针对这些项目的映射代码如下所示:NHibernate查询映射集合

<bag name="Entries" cascade="all-delete-orphan"> 
    <key column="UserID" /> 
    <one-to-many class="MyApp.Entities.Entry, MyApp.Entities" /> 
</bag> 

现在我有一个页面,在这里我想与登录用户的所有条目显示网格。为此,我可以简单地将当前用户的“Entries”属性绑定到网格“DataSource” - 属性。这也可以正常工作,但这也意味着内置分页功能(Telerik RadGrid)的网格对数据库性能没有任何影响,因为每次显示网格时都会加载所有条目。

因此,我可以应用我的自定义分页,其中我只获取需要显示网格当前页面的行。一个典型的Linq2NHibernate查询看起来是这样的:

var query = from entry in Session.Linq<Entry>() 
        where entry.User == currentUser 
        select entry; 
query.Skip(pageNum * pageSize).Take(pageSize).ToList(); 

使用这种方法,我需要altough NHibernate的已经做了用户和条目之间的映射致以库...

我的问题是:如果我使用LINQ直接查询我的“用户”对象的“条目”集合 - 这是否意味着所有条目将从数据库加载,然后在内存中过滤,或者将其转换为真正的“数据库” - 查询,这样我可以使用这种更舒适的方法来实现分页?

例子:

myGrid.DataSource = currentUser.Entries.Skip(pageNum * pageSize).Take(pageSize).ToList(); 

J4I:当然,我在映射文件中使用懒加载...

预先感谢您!

+0

重要提示: 与此同时,我发现样本linq-expression生成非常难看的SQL代码,实际上使用外部左连接来比较“User”属性。但是,升级到NH3和嵌入式linq提供程序可以解决此问题并输出更多优化的代码! 所以,如果你考虑使用Linq2NHibernate - 去NH3! – 2010-08-29 00:40:16

回答

0

集合上的LINQ将始终是LINQ到对象,因为它们不会实现IQueryable,因此您将在内存中加载所有内容。

查询是目前唯一可行的方法。

+0

NH3 linq提供者的情况仍然如此吗? – DanP 2010-08-29 11:40:30

+0

是的,提供者位于查询引擎之上;收集管理没有改变。您可以对实体集合执行LINQ查询,但不能直接对检索到的对象执行查询。 – 2010-08-29 13:01:09

+0

感谢您的确认..这有点令人失望,因为这会让linq的使用更加连贯。我猜测这会导致收藏中的肮脏跟踪等问题。对? – DanP 2010-08-30 12:37:42