从 IQueryOver 获取计数而不从数据库加载行
Get Count from IQueryOver without loading rows from DB
有了 IQueryOver,如何从中获取 行计数,而不从数据库加载所有行?
QueryOver 有 RowCount() 方法,但如果底层查询有 group-by 或 distinct,它丢弃它们。
***** 更新 *****
SQL 为 QueryOver.RowCount 生成(如您所见,它丢弃了 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'
和
SQL 为 QueryOver 生成:
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'
我认为 IQueryOver 不支持,但请不要引用我的话。
虽然我在 ICriteria 中使用它..
crit.SetProjection(Projections.Count(Projections.Distinct(Projections.Id())));
终于找到解决办法了。
将 MyMsSql2008Dialect 注入 nhibernate.dialect 值。
此 class 将行数插入名为 #TempCount 的临时 table;现在您可以在之后从#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>();
有了 IQueryOver,如何从中获取 行计数,而不从数据库加载所有行? QueryOver 有 RowCount() 方法,但如果底层查询有 group-by 或 distinct,它丢弃它们。
***** 更新 *****
SQL 为 QueryOver.RowCount 生成(如您所见,它丢弃了 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'
和
SQL 为 QueryOver 生成:
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'
我认为 IQueryOver 不支持,但请不要引用我的话。
虽然我在 ICriteria 中使用它..
crit.SetProjection(Projections.Count(Projections.Distinct(Projections.Id())));
终于找到解决办法了。 将 MyMsSql2008Dialect 注入 nhibernate.dialect 值。 此 class 将行数插入名为 #TempCount 的临时 table;现在您可以在之后从#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>();