2013-03-20 61 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