nHibernate投影 - 分页和不同

时间:2012-12-05 10:27:37

标签: nhibernate pagination sql-server-2008-r2 distinct nhibernate-projections

我试图解决的高级问题是在搜索子集合中可能存在的内容时重复数据删除分页。

我正在采取的方法是创建一个独特的投影,其中包含与我的DTO相关的信息。我也知道这些值在每一行之间都没有变化。

criteria.SetProjection(
  Projections.Distinct(Projections.ProjectionList()
    .Add(Projections.Alias(Projections.Property("Id"), "Id"))
    .Add(Projections.Alias(Projections.Property("Title"), "Title"))
    .Add(Projections.Alias(Projections.Property("Firstname"), "Firstname"))
    .Add(Projections.Alias(Projections.Property("Surname"), "Surname"))
    .Add(Projections.Alias(Projections.Property("DateCreated"), "DateCreated"))));

当我引入分页/排序元素时会出现问题。

看看NH Profiler,我看到的SQL就像: -

SELECT TOP (20 /* @p0 */) y0_,
  y1_,
  y2_,
  y3_,
  y4_
FROM   
(
  SELECT distinct 
    this_.Id as y0_,
    this_.Title as y1_,
    this_.Firstname as y2_,
    this_.Surname as y3_,
    this_.DateCreated as y4_,
    ROW_NUMBER() 
      OVER(ORDER BY this_.Firstname DESC, this_.Surname DESC) 
     as __hibernate_sort_row
  FROM   Users this_
) as query
WHERE  query.__hibernate_sort_row > 20 /* @p1 */
ORDER  BY query.__hibernate_sort_row;

我的目的是获取DISTINCT投影,因为ROW_NUMBER()使每一行都是唯一的。

我遇到过这篇博文,其中描述了我遇到的同样问题。

http://www.daczkowski.net/2010/09/07/rows-duplication-for-certain-nhibernate-queries-%E2%80%93-workaround/

提供的解决方案涉及更改nHibernate MS SQL代码;这是一个选项,但我渴望避免。是否有更新版本的nHibernate可以解决这个问题呢?

修改

在nHibernate 3.3.1中修复 - 请参阅下面的答案。

2 个答案:

答案 0 :(得分:1)

要删除这些重复项,我倾向于在进行分页时将集合属性的获取模式设置为“Select”或“Lazy”(这样,禁用映射的“Eager”或“Join”获取模式)

假设您有一个属性Children,这将导致删除投影并添加:

criteria.SetFetchMode("Children", FetchMode.Select);

criteria.SetResultTransformer(NHibernate.Transform.Transformers.DistinctRootEntity).List();

答案 1 :(得分:0)

经过一些进一步的研究,我现在找到了一个我很满意的解决方案。

根据这个: -

https://nhibernate.jira.com/browse/NH-2492

该错误已在nHibernate 3.3.1.CR1中解决。

我刚刚下载了nHibernate 3.3.1 stable,并成功使用了相同的策略而没有重复。

对于那些感兴趣的人,nh 3.3.1吐出以下SQL。

SELECT distinct TOP (20 /* @p0 */) this_.Id as y0_,
  this_.Title as y1_,
  this_.Firstname       as y2_,
  this_.Surname     as y3_,
  this_.DateCreated  as y4_,
 FROM   Users this_
ORDER  BY this_.Firstname desc,
          this_.Surname desc;