2013-03-20 45 views
2

我正在使用傳統的SQLBase數據庫,並試圖用NHibernate設置一個新項目。可以改變NHibernate的格式來制定綁定變量嗎?

的一個大問題是格式SQLBase預計在SQL綁定變量是。格式必須是明確

INSERT INTO ... VALUES (:1,:2,:3); 
SELECT ... FROM TABLE WHERE ID=:1 AND NAME=:2; 

現在NHibernate的使用「:P0,:P1,...」格式綁定變量,其給出了一個SQLBase「無效程序綁定變量」 SQL例外。

的問題是「P」的號碼前,也該參數從0開始 - SQLBase必須參數從1開始

有沒有什麼辦法可以設置/改變NHibernate的砸「 p「的綁定變量,並且也從1開始而不是0?我能夠在我的類映射中使用sql-insert,sql-update和sql-delete映射更改INSERT,UPDATE和DELETE的參數格式,但是我發現更改SELECT參數的唯一方法是編寫大量的命名查詢到我的映射。

顯然這不是首選的方法。有沒有更好的方法來改變綁定變量的生成方式?我已經創建了自己的Driver(繼承自OleDbDriver)和Dialect(來自GenericDialect),並且改變了一些東西使SQLBase在第一位工作。

我也試着設置

private static string ToParameterName(int index) 
{ 
    return "p" + index; 
} 

返回的String.Empty,但無濟於事。但是,即使是想從參數中刪除「P」字頭的我仍然有他們的開始,0而不是1

任何機會,以改變這種行爲或NHibernate的問題?

編輯:現在我也試着改變一些其他參數功能:

string ISqlParameterFormatter.GetParameterName(int index) 
     { 
      int ret = index + 1; 
      return (NamedPrefix + ret); 
     } 

     private void SetCommandParameters(IDbCommand cmd, SqlType[] sqlTypes) 
     { 
      for (int i = 0; i < sqlTypes.Length; i++) 
      { 
       int ret = i + 1; 
       string paramName = ret.ToString(); 
       IDbDataParameter dbParam = GenerateParameter(cmd, paramName, sqlTypes[i]); 
       cmd.Parameters.Add(dbParam); 
      } 
     } 

     protected override void InitializeParameter(IDbDataParameter dbParam, string name, SqlType sqlType) 
     { 
      if (sqlType == null) 
      { 
       throw new QueryException(String.Format("No type assigned to parameter '{0}'", name)); 
      } 
      name = name.Remove(0, 1); 
      dbParam.ParameterName = (Int32.Parse(name) + 1).ToString(); 
      dbParam.DbType = sqlType.DbType; 
     } 

隨着這些變化的SQL參數「:1,:2」等等,但它也打破了綁定 - 現在參數是不是在所有:(

EDIT2附加到查詢:下面是完整的驅動程序和方言代碼:

namespace NHSQLBase 
{ 
    public class SQLBaseDriver : OleDbDriver, ISqlParameterFormatter 
    { 
     public override bool UseNamedPrefixInSql 
     { 
      get 
      { 
       return true; 
      } 
     } 

     public override bool UseNamedPrefixInParameter 
     { 
      get 
      { 
       return false; 
      } 
     } 

     public override string NamedPrefix 
     { 
      get 
      { 
       return ":"; 
      } 
     } 

     private static string ToParameterName(int index) 
     { 
      return (index + 1).ToString(); 
     } 


     string ISqlParameterFormatter.GetParameterName(int index) 
     { 
      int ret = index + 1; 
      return (NamedPrefix + ret); 
     } 

     private void SetCommandParameters(IDbCommand cmd, SqlType[] sqlTypes) 
     { 
      for (int i = 0; i < sqlTypes.Length; i++) 
      { 
       int ret = i + 1; 
       string paramName = ret.ToString(); 
       IDbDataParameter dbParam = GenerateParameter(cmd, paramName, sqlTypes[i]); 
       cmd.Parameters.Add(dbParam); 
      } 
     } 

     protected override void InitializeParameter(IDbDataParameter dbParam, string name, SqlType sqlType) 
     { 
      if (sqlType == null) 
      { 
       throw new QueryException(String.Format("No type assigned to parameter '{0}'", name)); 
      } 
      name = name.Remove(0, 1); 
      dbParam.ParameterName = (Int32.Parse(name) + 1).ToString(); 
      dbParam.DbType = sqlType.DbType; 
     } 
    } 

    public class SQLBaseDialect : GenericDialect 
    { 
     public override string ForUpdateString 
     { 
      get 
      { 
       return " "; 
      } 
     } 

     public override bool ForUpdateOfColumns 
     { 
      get 
      { 
       return true; 
      } 
     } 

     public override string GetForUpdateString(string aliases) 
     { 
      return " for update of " + aliases; 
     } 

     public override bool SupportsOuterJoinForUpdate 
     { 
      get 
      { 
       return false; 
      } 
     } 

     public override bool SupportsParametersInInsertSelect 
     { 
      get 
      { 
       return false; 
      } 
     } 
    } 
} 
+0

可能是一個愚蠢的評論,但你嘗試過你的ToParameterName回報(指數+ 1)的ToString()? – jbl 2013-03-20 10:22:28

+1

唉,試圖改變ToParameterName字符串不會改變任何東西。即使有你的建議,參數仍然被命名爲「p0,p1」,依此類推:( – 2013-03-20 10:23:21

+0

有沒有機會發布你的方言源代碼? – mickfold 2013-03-20 10:27:55

回答

1

有點反覆試驗後,認爲我找到了你問題的根源。主要問題似乎是由OleDbDriver繼承的SQLBaseDriver造成的。一旦這被改爲ReflectionBasedDriver並且構造函數被正確填充,我就能夠執行插入而沒有任何問題。

請參閱下面的驅動程序和方言的工作版本。

需要注意的一點是,.Net數據提供程序dll for SQLBase,Gupta.SQLBase.Data.dll必須與NHibernate.dll位於同一文件夾才能使用。

public class SQLBaseDriver : NHibernate.Driver.ReflectionBasedDriver 
{ 
    public SQLBaseDriver() 
     : base("Gupta.SQLBase.Data", 
       "Gupta.SQLBase.Data.SQLBaseConnection", 
       "Gupta.SQLBase.Data.SQLBaseCommand") 
    { 

    } 
    public override bool UseNamedPrefixInSql 
    { 
     get { return true; } 
    } 

    public override bool UseNamedPrefixInParameter 
    { 
     get { return false; } 
    } 

    public override string NamedPrefix 
    { 
     get { return ":"; } 
    } 
} 

方言代碼:

public class SQLBaseDialect : GenericDialect 
{ 
    public override string ForUpdateString 
    { 
     get { return " "; } 
    } 

    public override bool ForUpdateOfColumns 
    { 
     get { return true; } 
    } 

    public override string GetForUpdateString(string aliases) 
    { 
     return " for update of " + aliases; 
    } 

    public override bool SupportsOuterJoinForUpdate 
    { 
     get { return false; } 
    } 

    public override bool SupportsParametersInInsertSelect 
    { 
     get { return false; } 
    } 
} 
+0

我現在試圖實現這個,而不是我的黑客解決方案(在某種程度上工作)。奇怪的是,我從驅動程序構造函數中得到一個InvalidCastException: System.InvalidCastException被捕獲 Message =類型爲「Gupta.SQLBase.Data.SQLBaseConnection」的對象無法轉換爲「System.Data.Common.DbConnection」。 – 2013-03-28 10:29:54

+0

你使用的是什麼版本的SQLBase?我在測試中使用了最新版本11.7。 – mickfold 2013-03-28 10:42:15

+0

我們正在使用11.5 – 2013-03-28 11:41:09