我在我的一个nhibernate映射文件中有一个命名的本机sql查询,如下所示:
<sql-query name="GetAllClients">
<return alias="clientList" class="IBeam.Core.Models.Client"/>
<![CDATA[
SELECT a.sname Name, a.scd Id
FROM :MASTER_USER.smast a,
:MASTER_USER.fa_ledmast b,
:TRAN_USER.fa_subledmast c
WHERE a.scd = c.subledcd
AND b.ledgercd = c.ledgercd
AND b.ledtypecd = 'SDR'
AND a.catflg = 'N'
group by a.scd, a.sname
order by a.sname
]]>
</sql-query>
我从我的c#代码运行此查询,如下所示:
var query = Repository.GetExecutingSession().GetNamedQuery("GetAllClients").SetString("MASTER_USER", "test$master").SetString("TRAN_USER", "test$tran");
var clients = query.List<Models.Client>();
但我收到错误:
参数MASTER_USER在查询中不作为命名参数存在。
我之前使用过命名查询并将参数传递给它,但从未作为模式名称。我认为它将整个:MASTER_USER.smast
视为表名,并没有区分参数名称。如何将模式名称作为参数传递给此查询?
我发现了这个Link所以我认为可以做到。但我不知道怎么做。
答案 0 :(得分:3)
首先,您的架构规范不能是SQL参数。替换需要由NH引擎执行,而不是由SQL引擎执行。因此,您的架构规范需要在NH占位符(带尖括号)
然后,您提供的Hibernate Link不允许将schema作为参数传递。它允许从config中提取默认架构。
也许(未尝试过)你可以尝试使用(非常粗略的)拦截器实现这样的东西:
public class SchemaSqlInterceptor : EmptyInterceptor, IInterceptor
{
public string MASTER_USER { get; set; }
public string TRAN_USER { get; set; }
NHibernate.SqlCommand.SqlString IInterceptor.OnPrepareStatement(NHibernate.SqlCommand.SqlString sql)
{
return sql.Replace("{MASTER_USER}", MASTER_USER).Replace("{TRAN_USER}", TRAN_USER);
}
}
然后:
var interceptor = new SchemaSqlInterceptor();
using (var session = sessionFactory.OpenSession(interceptor))
{
interceptor.MASTER_USER = "test$master";
interceptor.TRAN_USER = "test$tran";
var query = session.GetNamedQuery("GetAllClients");
var clients = query.List<Models.Client>();
session.Close();
}
您的查询是:
<sql-query name="GetAllClients">
<return alias="clientList" class="IBeam.Core.Models.Client"/>
<![CDATA[
SELECT a.sname Name, a.scd Id
FROM {MASTER_USER}.smast a,
{MASTER_USER}.fa_ledmast b,
{TRAN_USER}.fa_subledmast c
WHERE a.scd = c.subledcd
AND b.ledgercd = c.ledgercd
AND b.ledtypecd = 'SDR'
AND a.catflg = 'N'
group by a.scd, a.sname
order by a.sname
]]>
</sql-query>