C# NHibernate本机SQL中的多重选择

C# NHibernate本机SQL中的多重选择,c#,sql,nhibernate,C#,Sql,Nhibernate,我用原生SQL创建了一个复杂的搜索查询。基本上是这样的: SELECT ID FROM t_Product WHERE Name LIKE @criteria SELECT publisher, count(*) as number FROM t_Product GROUP BY publisher 它有2个SELECT语句,我希望它在一次往返中被发送到DB服务器 但我不知道如何在Nhibernate实现这一点 我考虑过以下几种选择,但似乎都不管用 使用CreateMultiQuery,但这只

我用原生SQL创建了一个复杂的搜索查询。基本上是这样的:

SELECT ID FROM t_Product WHERE Name LIKE @criteria
SELECT publisher, count(*) as number FROM t_Product GROUP BY publisher
它有2个
SELECT
语句,我希望它在一次往返中被发送到DB服务器

但我不知道如何在Nhibernate实现这一点

我考虑过以下几种选择,但似乎都不管用

  • 使用
    CreateMultiQuery
    ,但这只接受HQL,不接受本机SQL
  • 使用
    CreateSQLQuery
    ,但调用List()只返回第一个
    SELECT
    语句的结果
  • 移动到存储过程不是一个选项,因为整个SQL都是动态的
  • 我们仍然使用NHibernate1.2,因此更高版本中的新功能也无法使用

  • 欢迎提供意见

    不可能使用NH版本1.2

    Futures是在2.1版中发布的,它允许您完全做到这一点

    e、 g

    var blogs=s.CreateCriteria()
    .SetMaxResults(30)
    .Future();
    var countOfVoices=s.CreateCriteria()
    .SetProjection(Projections.Count(Projections.Id()))
    .未来价值();
    

    因此,您要么升级,要么返回ADO.NET并使用多个记录集,要么使用现有的记录集!对不起

    我认为这是不可能的,因为两个查询都是select

    您可以在第一个查询之后尝试使用分号,并在它们之间使用两个换行符,这对于某些数据库是必需的。我成功地运行了这样的查询脚本。如果它运行,请使用调试器查看返回的内容


    如果这不起作用,您需要单独往返或切换到HQL/Type。

    < P>这将是特定于场景的,但是如果您被NH版本1.2所困扰,并且取消往返是您的目标,那么您可以考虑使用子选择重写这个作为单个查询。

    大致如下:

    SELECT publisher, count(*) as number, 
    (SELECT ID FROM t_Product WHERE Name LIKE @criteria) As theId 
    FROM t_Product GROUP BY publisher
    
    如果您的子查询只返回一个值,则该方法将有效。

    您可以像这样使用多查询“Hack”:

    SELECT ID FROM t_Product WHERE Name LIKE @criteria
    SELECT publisher, count(*) as number FROM t_Product GROUP BY publisher
    
    程序:

    CREATE PROCEDURE [dbo].[proc_Name]
    AS BEGIN
        SELECT * FROM t_Question where ...
        SELECT * FROM t_Question where ........
    END
    
    NHibernate查询代码:

    public void ProcdureMultiTableQuery()
    {
        var session = Session;
        var procSQLQuery = session.CreateSQLQuery("exec [proc_Name] ?,?");// prcodure returns two table
        procSQLQuery.SetParameter(0, userId);
        procSQLQuery.SetParameter(1, page);
        procSQLQuery.AddEntity(typeof(Question));
    
        var multiResults = session.CreateMultiQuery()
            .Add(procSQLQuery)
            // More table your procedure returns,more empty SQL query you should add
            .Add(session.CreateSQLQuery(" ").AddEntity(typeof(Question))) // the second table returns Question Model
            .List();
        if (multiResults == null || multiResults.Count == 0)
        {
            return;
        }
        if (multiResults.Count != 2)
        {
            return;
        }
        var questions1 = ConvertObjectsToArray<Question>((System.Collections.IList)multiResults[0]);
        var questions2 = ConvertObjectsToArray<Question>((System.Collections.IList)multiResults[1]);
    }
    
    static T[] ConvertObjectsToArray<T>(System.Collections.IList objects)
    {
        if (objects == null || objects.Count == 0)
        {
            return null;
        }
        var array = new T[objects.Count];
        for (int i = 0; i < array.Length; i++)
        {
            array[i] = (T)objects[i];
        }
        return array;
    }
    
    public void ProcdureMultiTableQuery()
    {
    var会话=会话;
    var procSQLQuery=session.CreateSQLQuery(“exec[proc\u Name]?,?”;//prcodure返回两个表
    procSQLQuery.SetParameter(0,userId);
    procSQLQuery.SetParameter(第1页);
    AddEntity(typeof(Question));
    var multiResults=session.CreateMultiQuery()
    .Add(procSQLQuery)
    //过程返回的表越多,应该添加的空SQL查询越多
    .Add(session.CreateSQLQuery(“”).AddEntity(typeof(Question))//第二个表返回问题模型
    .List();
    if(multiResults==null | | multiResults.Count==0)
    {
    返回;
    }
    如果(multiResults.Count!=2)
    {
    返回;
    }
    var questions1=ConvertObjectsToArray((System.Collections.IList)multiResults[0]);
    var questions2=ConvertObjectsToArray((System.Collections.IList)multiResults[1]);
    }
    静态T[]ConvertObjectsToArray(System.Collections.IList对象)
    {
    if(objects==null | | objects.Count==0)
    {
    返回null;
    }
    var数组=新的T[objects.Count];
    for(int i=0;i
    你为什么反对用HQL编写它?正如我所料:我认为它不管用。使用HQL/Criteria或两个往返。我使用NH3.2做了一些测试,它似乎也不支持原生SQL。我想这是因为它是建立在多queryql之上的,QueryOver和ICriteria都受支持。从未尝试过使用本机SQL,因为您向我们展示的SQL示例可以非常简单地转换为HQL,但我怀疑您有更复杂的SQL!谢谢,你给了我另一种思考方式。让我试试是否可以按照您的建议更改我的查询。我应该提到的另一个警告是,您的“外部”查询将始终需要至少返回一行,以便子选择查询返回结果,因此请确保您计划:)