C# 如何将变量中的架构名称传递给nHibernate';什么是命名查询?

C# 如何将变量中的架构名称传递给nHibernate';什么是命名查询?,c#,nhibernate,C#,Nhibernate,我的一个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,

我的一个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>
var query = Repository.GetExecutingSession().GetNamedQuery("GetAllClients").SetString("MASTER_USER", "test$master").SetString("TRAN_USER", "test$tran");
var clients = query.List<Models.Client>();

我从我的c代码运行这个查询,如下所示:

<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>
var query = Repository.GetExecutingSession().GetNamedQuery("GetAllClients").SetString("MASTER_USER", "test$master").SetString("TRAN_USER", "test$tran");
var clients = query.List<Models.Client>();
var query=Repository.GetExecutingSession().GetNamedQuery(“GetAllClient”).SetString(“MASTER_用户”、“test$MASTER”).SetString(“TRAN_用户”、“test$TRAN”);
var clients=query.List();
但我得到了一个错误: 参数MASTER_USER在查询中不作为命名参数存在。 我以前使用过命名查询并将参数传递给它,但从未将其作为模式名。我认为它将整个
:MASTER_USER.smast
视为一个表名,而不是区分参数名。如何将架构名称作为参数传递到此查询


我发现了这个,所以我认为这是可以做到的。但是我不知道怎么做。

首先,您的模式规范不能是SQL参数。替换将需要由NH引擎执行,而不是由SQL引擎执行。因此,您的模式规范需要位于NH占位符中(带尖括号)

然后,您提供的Hibernate链接不允许将架构作为参数传递。它允许从配置中提取默认模式

也许(未尝试过)您可以尝试类似的方法,使用(非常粗糙的)拦截器实现:

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();
    }
var interceptor=newschemasqlinterceptor();
使用(var session=sessionFactory.OpenSession(拦截器))
{
interceptor.MASTER\u USER=“test$MASTER”;
interceptor.TRAN_USER=“test$TRAN”;
var query=session.GetNamedQuery(“GetAllClients”);
var clients=query.List();
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>


谢谢jbl。我现在正在做类似的事情。我对拦截器接口一无所知。我所做的是在使用
GetNamedQuery
获取查询之后,我手动创建另一个
IQuery
,并手动替换模式名称。您的实现将使这个替换逻辑保持在一个位置。我现在就试试这个。谢谢。很高兴这有帮助。请记住,这是一个粗略的实现(不处理模式占位符和同名实体之间的冲突,当拦截器中没有提供模式值时不处理点)。我想稍微修改一下这个实现,这样只有当查询是一个命名查询时才会发生拦截——一个在hbm文件中定义的查询,而不是由NHibernate生成的查询。有什么输入吗?我必须说我不知道如何在拦截器中跟踪它。我只是在考虑占位符的命名约定,防止它与实体名称混淆。