【问题标题】:How to select from a subselect on NHibernate如何从 NHibernate 上的子选择中进行选择
【发布时间】: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


    【解决方案1】:

    我找到了问题的解决方案,这是一个非常大的技巧,但它可以按预期工作。

    我必须获取生成的 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;
    }
    

    【讨论】:

      【解决方案2】:
      DetachedCriteria criteriaEmployees = DetachedCriteria.For<Employees>();
      criteriaEmployees.SetProjection(Projections.CountDistinct("FirstName"));
      ICriteria executableCriteria = criteriaEmployees.GetExecutableCriteria(Session);
      int count = executableCriteria.UniqueResult<int>();
      

      【讨论】:

      • 这是我的解决方案。遗憾的是,没有关于这方面的真正和文档......所以如果你不知道它存在或错误地偶然发现它,你就会遇到问题。
      【解决方案3】:

      DetachedCriteria 可用于创建子查询。 documentation 中有一些示例。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多