我想将任何给定的选择查询转换为等效计数查询。选择查询可以是有效的 SQL 或 HQL 查询。以下是我的尝试。
/// <summary>
/// Converts select query into equivalent count query
/// </summary>
protected string ConvertToCountQuery(string selectQuery)
{
if (string.IsNullOrWhiteSpace(selectQuery))
{
return string.Empty;
}
string[] selectParts = selectQuery.ToLower().Split(new string[] { "select" }, StringSplitOptions.RemoveEmptyEntries);
string[] fromParts = selectParts[0].Split(new string[] { "from" }, StringSplitOptions.RemoveEmptyEntries);
selectParts[0] = string.Format("select count(*) from{0}", fromParts[1]);
return string.Concat(selectParts);
}
它适用于SQL查询,因为它们不区分大小写,但是对于HQL查询,它会丢失大小写。如何在仍获取等效计数查询的同时保留大小写。
SQL 的示例测试数据:
select u.username, u.email, u.first_name, u.last_name from users u where u.username like '% %';
SQL 的预期输出:
select count(*) from users u where u.username like '% %';
HQL 的示例测试数据:
select u.Username, u.Email, u.FirstName, u.LastName from User u where u.Username like '% %';
HQL 的预期输出:
select count(*) from Users u where u.Username like '% %';
请注意 HQL 查询中的区分大小写。
好的,我自己找到了解决方案。
/// <summary>
/// Converts select query into equivalent count query
/// </summary>
public static string ConvertToCountQuery(string selectQuery)
{
if (string.IsNullOrWhiteSpace(selectQuery) || !selectQuery.ToLower().Contains("select"))
{
return string.Empty;
}
return string.Concat(
"select count(*)",
selectQuery.Substring(selectQuery.ToLower().IndexOf(" from")));
}
我会尝试将给定的查询放入子查询中:
var countQuery = string.Format("select count(*) from ({0})", selectQuery);
它会将其转换为此类查询:
select count(*) from (select ... from User u where u.Username like '% %');
我不知道它是否有效。Oracle 需要支持这一点(FROM 子句中的子查询(。HQL也需要支持它(它通常在很多事情上都是透明的,所以有希望(。如果没有,我认为通过合理的努力和可接受的可靠性是不可能的。
请考虑对此类任务使用 linq 或 query over,因为这些 API 在运行时可靠地构建查询方面要灵活得多。AFAIK,两者都有内置的计数支持。