2013-04-02 73 views
1

我有一個名爲原生SQL查詢中的我的NHibernate映射文件之一,如下所示:如何將變量中的模式名稱傳遞給nHibernate的命名查詢?

<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,所以我認爲它可以做到。但我不知道如何。

回答

3

首先,您的模式規範不能是SQL參數。替換將需要由NH引擎執行,而不是由SQL引擎執行。因此,您的架構規範需要位於NH佔位符中(使用尖括號)

然後,您提供的Hibernate鏈接不允許將架構作爲參數傳遞。它允許從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> 
+0

謝謝jbl。我現在正在做類似的事情。我不知道Interceptor接口。我在做的是在使用'GetNamedQuery'獲得查詢後,我手動創建了另一個'IQuery',並且手動替換了模式名稱。你的實現將保持這個替換邏輯在一個地方。我現在就試試這個。 – mridula

+0

thx。很高興幫助。請記住,這是粗略的實現(不處理模式佔位符與同名實體之間的衝突,在攔截器中未提供模式值時不處理點) – jbl

+0

。我正在尋找修改這個實現的一點點,以便只有當查詢是一個命名查詢 - 一個在hbm文件中定義的查詢,而不是由NHibernate生成的。任何投入? – mridula

相關問題