C# NHibernate本机SQL中的多重选择
我用原生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,但这只
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,不接受本机SQLCreateSQLQuery
,但调用List()只返回第一个SELECT
语句的结果欢迎提供意见 不可能使用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!谢谢,你给了我另一种思考方式。让我试试是否可以按照您的建议更改我的查询。我应该提到的另一个警告是,您的“外部”查询将始终需要至少返回一行,以便子选择查询返回结果,因此请确保您计划:)