Как выбрать из подвыбора на NHibernate - PullRequest
1 голос
/ 21 сентября 2011

Как мне сопоставить этот SQL с помощью API-интерфейса NHibernate Criteria?

Sql:

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

Это очень очень простой запрос, в моем запросе SubSelect гораздо более сложный.

Итак, есть идеи?

Ответы [ 3 ]

2 голосов
/ 03 октября 2011

Я нашел решение для вопроса, это очень большой взлом, но он работает как положено.

Мне пришлось получить сгенерированный 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;
}
1 голос
/ 22 сентября 2011
DetachedCriteria criteriaEmployees = DetachedCriteria.For<Employees>();
criteriaEmployees.SetProjection(Projections.CountDistinct("FirstName"));
ICriteria executableCriteria = criteriaEmployees.GetExecutableCriteria(Session);
int count = executableCriteria.UniqueResult<int>();
0 голосов
/ 22 сентября 2011

DetachedCriteria можно использовать для создания подзапросов.Некоторые примеры приведены в документации .

...