【问题标题】:Get Count from IQueryOver without loading rows from DB从 IQueryOver 获取计数而不从数据库加载行
【发布时间】:2017-07-30 10:30:35
【问题描述】:

拥有 IQueryOver,我如何从它获取 行数,而不从数据库中加载所有行? QueryOver 有 RowCount() 方法,但如果底层查询有 group-bydistinct,它会丢弃它们。

***** 更新 *****

QueryOver.RowCount 生成 SQL(如您所见,它丢弃了 DISTINCT):

exec sp_executesql N'
SELECT count(*) as y0_ 
FROM dbo.OPR_STL_DCM this_ 
left outer join dbo.OPR_STL_LN_ITM lineitem1_ 
on 
this_.DCM_ID=lineitem1_.DCM_ID 
left outer join dbo.OPR_STL_DY_LN_ITM daylineite2_ 
on 
lineitem1_.DCM_ID=daylineite2_.DCM_ID and 
lineitem1_.TND_ID=daylineite2_.TND_ID 
WHERE 
daylineite2_.BSNS_DT >= @p0 and 
daylineite2_.BSNS_DT <= @p1'
,N'@p0 datetime,@p1 datetime',@p0='2016-07-22 00:00:00',@p1='2016-08-21 23:59:59'

QueryOver 生成的 SQL:

exec sp_executesql N'
SELECT distinct this_.DCM_ID as y0_, 
    this_.RTL_STR_ID as y1_, 
    this_.WS_ID as y2_, 
    this_.BSNS_DT as y3_, 
    this_.OPR_ID as y4_, 
    this_.TND_RPSTY_ID as y5_, 
    this_.IS_CNC as y6_, 
    this_.IS_SNG_DY_STL as y7_, 
    this_.BGN_DT_TM as y8_, 
    this_.END_DT_TM as y9_ 
FROM dbo.OPR_STL_DCM this_ 
left outer join dbo.OPR_STL_LN_ITM lineitem1_ 
on 
this_.DCM_ID=lineitem1_.DCM_ID 
left outer join dbo.OPR_STL_DY_LN_ITM daylineite2_ 
on 
lineitem1_.DCM_ID=daylineite2_.DCM_ID and 
lineitem1_.TND_ID=daylineite2_.TND_ID 
WHERE daylineite2_.BSNS_DT >= @p1 and 
daylineite2_.BSNS_DT <= @p2'
,N'@p1 datetime,@p2 datetime',@p0=20,@p1='2016-07-22 00:00:00',@p2='2016-08-21 23:59:59'

【问题讨论】:

  • 如您所见,RowCount 方法并没有得到查询结果的实际计数!

标签: nhibernate queryover icriteria


【解决方案1】:

我认为 IQueryOver 不支持这一点,但请不要引用我的话。

虽然我得到了它与 ICriteria 的合作..

 crit.SetProjection(Projections.Count(Projections.Distinct(Projections.Id())));

【讨论】:

    【解决方案2】:

    终于找到了解决办法。 将 MyMsSql2008Dialect 注入 nhibernate.dialect 值。 此类将行数插入名为#TempCount 的临时表中;现在您可以在之后从#TempCount 读取行数。请注意,这必须在会话中完成。

    public class MyMsSql2008Dialect : MsSql2008Dialect
    {
        public override SqlString GetLimitString(SqlString queryString, SqlString offset, SqlString limit)
        {
            SqlString limitString = base.GetLimitString(queryString, offset, limit);
    
            SqlStringBuilder ssb = new SqlStringBuilder();
    
            string resultCountQuery = string.Format(
                @"
                    INSERT INTO #TempCount
                    SElECT COUNT(*) AS Count FROM 
                    (
                        {0}
                    ) AS _queryResult 
                "
                , queryString);
    
            ssb.Add(resultCountQuery);
    
            SqlStringBuilder newLimitString  = new SqlStringBuilder();
            newLimitString.Add(limitString).Add(Environment.NewLine).Add(ssb.ToSqlString());
    
            return newLimitString.ToSqlString();
        }
    }
    

    并获取行数:

    int rowsCount = session.CreateSQLQuery("SELECT TOP 1 * FROM #TempCount").UniqueResult<int>();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-11
      • 1970-01-01
      相关资源
      最近更新 更多