2011-08-24 64 views
0

如何转换下面的SQL NH Queryover,转换为NHibernate的Queryover

select COUNT(*) 
from 
(select p.CODE,sl.BATCH from STORELOCATION sl 
right join PRODUCT p on p.CODE = sl.CODE 
group by p.CODE,sl.BATCHID) 
as t 
+0

其实这是更简化的版本的阙我想,基本的想法是获取具有多个分组的查询的行数,以将其用于分页。我不知道如何让内部查询部分工作,这就是为什么添加这个问题。 –

回答

1

我设法这个使用自定义投影,如果有人有兴趣的代码如下来实现,

[Serializable] 
    public class GroupCountProjection : SimpleProjection 
    { 
     private PropertyProjection[] _projections; 

     public GroupCountProjection(PropertyProjection[] projections) 
     { 
      _projections = projections; 
     } 

     public override bool IsAggregate 
     { 
      get { return true; } 
     } 

     public override IType[] GetTypes(ICriteria criteria, ICriteriaQuery criteriaQuery) 
     { 
      return new IType[] { NHibernateUtil.Int32 }; 
     } 

     public override SqlString ToSqlString(ICriteria criteria, int position, ICriteriaQuery criteriaQuery, IDictionary<string, IFilter> enabledFilters) 
     { 
      SqlStringBuilder result = new SqlStringBuilder() 
       .Add(" count(*) as y") 
       .Add(position.ToString()) 
       .Add("_ from (select "); 
      for (int index = 0; index < _projections.Length; index++) 
      { 
       PropertyProjection projection = _projections[index]; 
       if (index > 0) 
        result.Add(","); 
       result.Add(projection.ToSqlString(criteria, ++position, criteriaQuery, enabledFilters)); 
      } 
      result.Add(" "); 
      return result.ToSqlString(); 
     } 

     public override string ToString() 
     { 
      return "select count(*)"; 
     } 

     public override bool IsGrouped 
     { 
      get { return true; } 
     } 

     public override SqlString ToGroupSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, 
                IDictionary<string, IFilter> enabledFilters) 
     { 
      SqlStringBuilder result = new SqlStringBuilder(); 
      for (int index = 0; index < _projections.Length; index++) 
      { 
       PropertyProjection projection = _projections[index]; 
       if (index > 0) 
        result.Add(","); 
       result.Add(StringHelper.RemoveAsAliasesFromSql(projection.ToSqlString(criteria, 0, criteriaQuery,enabledFilters))); 
      } 
      result.Add(") as tbly"); 
      return result.ToSqlString(); 
     } 
    } 

这里的构造投影需要通过与所有组的投影一样,

var countQuery = GetProductQuery(); // this is the queryover 
      countQuery 
       .Select(new GroupCountProjection(new[]{ 
        Projections.Group(() => _productAlias.Code), 
        Projections.Group(() => _storeLocationAlias.Batch), 
       })); 
int resultCount = (int)countQuery.List<object>().SingleOrDefault(); 
1

我已经尝试过使用QueryOver和别名来解决;抱歉,但我现在无法测试此代码。 :(

 ProductModel myProd = null; 
     StoreLocationModel myLocation = null; 

     var qOver = _HibSession.QueryOver<ProductModel>(() => myProd) 
      .JoinAlias(() => myProd.Locations,() => myLocation, JoinType.LeftOuterJoin) 
      .Select(Projections.GroupProperty(myProd.CODE), Projections.GroupProperty(myLocation.BATCHID)) 
      .RowCount(); 

我希望这是有帮助的!

+0

感谢您的回答,由此生成的SQL没有Group By部分,它给出的总行数不同于group by子句返回的行数。 –

+0

@Adipa Gunasekara:好的,尝试使用.Select(Projections.Group(()=> myProd.CODE),Projections.Group(()=> myLocation.BATCHID))。我很抱歉,但我不能再试一次:( – Faber

+0

它也给出了相同的结果没有分组,但我已经尝试了很多不同的组合,但只要我尝试获得rowCount组子句在查询中缺失,所以我相信只有这样做的方法是将查询作为内部查询执行,正如我在问题中提到的那样,但我仍然没有清楚的想法,甚至可能使用NH Queryover。 –