3

我正在使用舊數據庫,並試圖將char轉換爲int以進行多對一映射。我知道這不是一個好主意,但是我堅持使用架構。多對一公式將表名添加到SQL關鍵字

我試圖用下面的映射做到這一點,但發現NHibernate將表名alias添加到關鍵字SQL_INTEGER

<many-to-one name="host" formula="CONVERT(alloc_code, SQL_INTEGER)" /> 

生成SQL

CONVERT(hostplacem0_.alloc_code, hostplacem0_.SQL_INTEGER) 

我發現this職位,但解決的辦法是不是一個可行的一個我的情況。

需要注意的一件事是,我們已經爲我們使用的DBMS(Sybase Advantage數據庫服務器)推出了自己的方言,因爲NHibernate不支持開箱即用。因此,我可以選擇修改此以解決此問題。我已經嘗試將SQL_INTEGER註冊爲關鍵字,但這沒有幫助。

+0

隨機想法,但您可以嘗試在同一個dialect文件中的RegisterFunctions,例如https://github.com/nhibernate/nhibernate-core/blob/master/src/NHibernate/Dialect/MsSql2000Dialect.cs 。 str聲明看起來很有趣 – jbl 2013-03-19 09:01:57

+0

感謝您的建議@jbl。事實證明,這是一個區分大小寫的問題。請參閱下面的答案。 – mickfold 2013-03-19 09:53:19

+0

thx爲後續行動 – jbl 2013-03-19 09:55:04

回答

1

花了好幾個小時通過NHibernate源,我終於能夠確定爲什麼RegisterKeyword("SQL_INTEGER")沒有工作。方法Template.RenderWhereStringTemplate用於生成公式SQL。此方法對其處理的每個字符串標記調用ToLowerInvariant(),因此,當方法檢查保留關鍵字列表時,它會查找sql_integer,因此找不到它。在我們自定義的話改變調用RegisterKeyword("sql_integer")後,產生正確的SQL:

CONVERT(hostplacem0_.alloc_code, SQL_INTEGER) 

對於完整性我也檢查,看看是否有可能在新的關鍵字注入由SessionFactoryImpl訪問方言類和調用RegisterKeyword通過反射,即

var factory_impl = factory as SessionFactoryImpl; 
if (factory_impl != null) 
{ 
    MethodInfo mInfoMethod = typeof(Dialect).GetMethod(
     "RegisterKeyword", 
     BindingFlags.Instance | BindingFlags.NonPublic, 
     Type.DefaultBinder, 
     new[] { typeof(string) }, 
     null); 

    mInfoMethod.Invoke(factory_impl.Dialect, new object[] { "sql_integer" }); 
} 

雖然此代碼工作NHibernate仍然發出不正確的SQL。不幸的是,每次使用Dialect.GetDialect方法請求一個方言對象時,NHibernate就會創建一個新的方言實例。

我想解決這個問題的唯一方法就是做我們所做的。根據我們的情況,完全創建自己的方言,或者從現有方言中進行分類,並將RegisterKeyword的呼叫添加到構造函數中。

相關問題