【发布时间】:2011-09-21 14:59:49
【问题描述】:
如何使用 NHibernate Criteria API 映射此 SQL?
Sql:
SELECT COUNT(*) FROM (
SELECT FirstName, LastName FROM Employees GROUP BY FirstName, LastName
) AS Query
这是一个非常简单的查询,我的查询有一个更复杂的 SubSelect。
那么,有什么想法吗?
【问题讨论】:
如何使用 NHibernate Criteria API 映射此 SQL?
Sql:
SELECT COUNT(*) FROM (
SELECT FirstName, LastName FROM Employees GROUP BY FirstName, LastName
) AS Query
这是一个非常简单的查询,我的查询有一个更复杂的 SubSelect。
那么,有什么想法吗?
【问题讨论】:
我找到了问题的解决方案,这是一个非常大的技巧,但它可以按预期工作。
我必须获取生成的 SQL 并用 SELECT COUNT(*) 查询包围它。这是执行此操作的代码:
public ISQLQuery BuildCountQuery(ICriteria criteria)
{
CriteriaImpl c = (CriteriaImpl)criteria;
SessionImpl s = (SessionImpl)c.Session;
string entityOrClassName = ExtractRealClassName(c);
SessionFactoryImpl factory = (SessionFactoryImpl)s.SessionFactory;
String[] implementors = factory.GetImplementors(entityOrClassName);
string implementor = implementors.Length == 0 ? null : implementors[0];
var persister = (IOuterJoinLoadable)factory.GetEntityPersister(implementor);
CriteriaLoader loader = new CriteriaLoader(persister, factory, c, implementor, s.EnabledFilters);
SqlString sql = loader.SqlString.Insert(0, "SELECT COUNT(*) FROM (");
sql = sql.Append(") AS Query");
var parameters = loader.Translator.CollectedParameters;
var sqlQuery = this.session.CreateSQLQuery(sql.ToString());
for (int i = 0; i < parameters.Count; i++)
sqlQuery.SetParameter(i, parameters.ElementAt(i).Value, parameters.ElementAt(i).Type);
return sqlQuery;
}
private string ExtractRealClassName(CriteriaImpl criteria)
{
Type rootEntityType = criteria.GetRootEntityTypeIfAvailable();
if (rootEntityType.GetInterfaces().Contains(typeof(INHibernateProxy)))
return criteria.GetRootEntityTypeIfAvailable().BaseType.FullName;
else
return criteria.EntityOrClassName;
}
【讨论】:
DetachedCriteria criteriaEmployees = DetachedCriteria.For<Employees>();
criteriaEmployees.SetProjection(Projections.CountDistinct("FirstName"));
ICriteria executableCriteria = criteriaEmployees.GetExecutableCriteria(Session);
int count = executableCriteria.UniqueResult<int>();
【讨论】:
DetachedCriteria 可用于创建子查询。 documentation 中有一些示例。
【讨论】: