如何将变量中的模式名称传递给nHibernate的命名查询?

时间:2013-04-02 05:52:33

标签: 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,
        :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所以我认为可以做到。但我不知道怎么做。

1 个答案:

答案 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>