2011-09-21 4 views
1

NHibernate Criteria API를 사용하여이 SQL을 어떻게 매핑 할 수 있습니까?NHibernate에서 subselect에서 선택하는 방법

SQL은 :

SELECT COUNT(*) FROM (
    SELECT FirstName, LastName FROM Employees GROUP BY FirstName, LastName 
) AS Query 

이 내 쿼리는 훨씬 더 복잡 하위 선택을 가지고, 아주 아주 간단한 쿼리입니다.

그럼, 어떤 생각일까요?

답변

2

질문에 대한 해결책을 찾았습니다. 매우 큰 해킹이지만 예상대로 작동합니다.

생성 된 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; 
} 
0

DetachedCriteria은 하위 쿼리를 만드는 데 사용할 수 있습니다. 일부 예제는 documentation에 있습니다.

1
DetachedCriteria criteriaEmployees = DetachedCriteria.For<Employees>(); 
criteriaEmployees.SetProjection(Projections.CountDistinct("FirstName")); 
ICriteria executableCriteria = criteriaEmployees.GetExecutableCriteria(Session); 
int count = executableCriteria.UniqueResult<int>(); 
+0

이것은 해결책입니다. 안타깝게도 이것에 대한 문서와 문서가 없기 때문에 ... 존재하지 않거나 실수로 넘어지면 문제가 발생합니다. –

관련 문제