我正在研究一个遗留的 SQLBase 数据库,并试图用 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 参数的唯一方法是编写大量命名查询到我的映射。
显然这不是首选方式。有没有更好的方法来改变绑定变量的生成方式?我已经制作了自己的驱动程序(继承自 OleDbDriver)和方言(继承自 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;
}
}
}
}