出现问题是因为较新的 Informix 驱动程序使用不同的连接,并且误解了布尔值。
我找到的解决方案是创建一个新的 NHibernate 驱动程序,继承自 NHibernate.Driver.IfxDriver。在查询执行之前处理参数。
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NHibernate;
using NHibernate.Driver;
using NHibernate.SqlCommand;
using NHibernate.SqlTypes;
namespace DataAccess
{
public class NHibernateCustomDriver : NHibernate.Driver.IfxDriver
{
public override IDbCommand GenerateCommand(CommandType type, SqlString sqlString, SqlType[] parameterTypes)
{
IDbCommand cmd = CreateCommand();
cmd.CommandType = type;
SetCommandTimeout(cmd);
SetCommandText(cmd, sqlString, parameterTypes);
SetCommandParameters(cmd, parameterTypes);
return cmd;
}
private void SetCommandText(IDbCommand cmd, SqlString sqlString, SqlType[] parameterTypes)
{
SqlStringFormatter formatter = GetSqlStringFormatter();
formatter.Format(sqlString);
int index = 0;
int count = 0;
string newCommand = formatter.GetFormattedText();
index = newCommand.IndexOf("?");
while (index >= 0)
{
if (parameterTypes[count].DbType == DbType.Boolean)
{
newCommand = newCommand.Substring(0, index) + "CAST(? AS BOOLEAN)" + newCommand.Substring(index + 1);
index = newCommand.IndexOf("?", index + 1);
}
count++;
index = newCommand.IndexOf("?", index + 1);
}
cmd.CommandText = newCommand;
}
private void SetCommandParameters(IDbCommand cmd, SqlType[] sqlTypes)
{
for (int i = 0; i < sqlTypes.Length; i++)
{
string paramName = ToParameterName(i);
IDbDataParameter dbParam = GenerateParameter(cmd, paramName, sqlTypes[i]);
cmd.Parameters.Add(dbParam);
}
}
private static string ToParameterName(int index)
{
return "p" + index;
}
}
}
NHibernate 配置必须设置为新类。
cfg.SetProperty("connection.driver_class", "DataAccess.NHibernateCustomDriver, DataAccess");
您还必须创建一个自定义类型来处理这些布尔值:
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NHibernate.Type;
namespace DataAccess
{
public class NHibernateUnixBooleanType : BooleanType
{
public override void Set(IDbCommand cmd, object value, int index)
{
cmd.Parameters[index] = CloneParameter(cmd, cmd.Parameters[index] as IDbDataParameter, value as bool?);
}
private IDbDataParameter CloneParameter(IDbCommand cmd, IDbDataParameter originalParameter, bool? value)
{
var clone = cmd.CreateParameter();
clone.DbType = DbType.String;
clone.Value = value.Value ? "t" : "f";
clone.ParameterName = originalParameter.ParameterName;
return clone;
}
}
}
并在映射文件上设置此类型:
<property name="Property" column="column" type="DataAccess.NHibernateUnixBooleanType, DataAccess"></property>