これに取り組んでから少し経ちましたが、現在、問題を検証するための作業プロジェクトはありませんが、これで問題が解決すると信じています.
これを解決した方法は、nHibernate プロジェクトのカスタム ビルドを行うことでした。以下の編集でOracleDataClientDriver.csファイルを編集しました。このファイルの現在のバージョンをダウンロードしたばかりで、修正を行ってから過去 2 年間でわずかに変更されていることに注意してください。nHibernate リポジトリから現在のバージョンのファイルを取得し、貼り付けようとしているコードとファイルを比較すると、変更が表示されます。私の変更は、行番号 (編集者による) 26、45、82-85 にあります。
修正のテーマは、nHibernate マッピング ファイル タイプから Oracle Data Type for XML へのマッピングを追加する必要があったことです。Oracle ドライバーはこのタイプを処理しますが、nHibernate でそれを使用するロジックがありませんでした。以下は、これに対する修正です。
貼り付け開始-----
using System.Data;
using System.Reflection;
using NHibernate.AdoNet;
using NHibernate.Engine.Query;
using NHibernate.SqlTypes;
using NHibernate.Util;
namespace NHibernate.Driver
{
/// <summary>
/// A NHibernate Driver for using the Oracle.DataAccess DataProvider
/// </summary>
/// <remarks>
/// Code was contributed by <a href="http://sourceforge.net/users/jemcalgary/">James Mills</a>
/// on the NHibernate forums in this
/// <a href="http://sourceforge.net/forum/message.php?msg_id=2952662">post</a>.
/// </remarks>
public class OracleDataClientDriver : ReflectionBasedDriver, IEmbeddedBatcherFactoryProvider
{
private const string driverAssemblyName = "Oracle.DataAccess";
private const string connectionTypeName = "Oracle.DataAccess.Client.OracleConnection";
private const string commandTypeName = "Oracle.DataAccess.Client.OracleCommand";
private static readonly SqlType GuidSqlType = new SqlType(DbType.Binary, 16);
private readonly PropertyInfo oracleDbType;
private readonly object oracleDbTypeRefCursor;
private readonly object oracleDbTypeXmlType;
/// <summary>
/// Initializes a new instance of <see cref="OracleDataClientDriver"/>.
/// </summary>
/// <exception cref="HibernateException">
/// Thrown when the <c>Oracle.DataAccess</c> assembly can not be loaded.
/// </exception>
public OracleDataClientDriver()
: base(
driverAssemblyName,
connectionTypeName,
commandTypeName)
{
System.Type parameterType = ReflectHelper.TypeFromAssembly("Oracle.DataAccess.Client.OracleParameter", driverAssemblyName, false);
oracleDbType = parameterType.GetProperty("OracleDbType");
System.Type oracleDbTypeEnum = ReflectHelper.TypeFromAssembly("Oracle.DataAccess.Client.OracleDbType", driverAssemblyName, false);
oracleDbTypeRefCursor = System.Enum.Parse(oracleDbTypeEnum, "RefCursor");
oracleDbTypeXmlType = System.Enum.Parse(oracleDbTypeEnum, "XmlType");
}
/// <summary></summary>
public override bool UseNamedPrefixInSql
{
get { return true; }
}
/// <summary></summary>
public override bool UseNamedPrefixInParameter
{
get { return true; }
}
/// <summary></summary>
public override string NamedPrefix
{
get { return ":"; }
}
/// <remarks>
/// This adds logic to ensure that a DbType.Boolean parameter is not created since
/// ODP.NET doesn't support it.
/// </remarks>
protected override void InitializeParameter(IDbDataParameter dbParam, string name, SqlType sqlType)
{
// if the parameter coming in contains a boolean then we need to convert it
// to another type since ODP.NET doesn't support DbType.Boolean
switch (sqlType.DbType)
{
case DbType.Boolean:
base.InitializeParameter(dbParam, name, SqlTypeFactory.Int16);
break;
case DbType.Guid:
base.InitializeParameter(dbParam, name, GuidSqlType);
break;
case DbType.Xml:
dbParam.ParameterName = base.FormatNameForParameter(name);
oracleDbType.SetValue(dbParam, oracleDbTypeXmlType, null);
break;
default:
base.InitializeParameter(dbParam, name, sqlType);
break;
}
}
protected override void OnBeforePrepare(IDbCommand command)
{
base.OnBeforePrepare(command);
CallableParser.Detail detail = CallableParser.Parse(command.CommandText);
if (!detail.IsCallable)
return;
command.CommandType = CommandType.StoredProcedure;
command.CommandText = detail.FunctionName;
IDbDataParameter outCursor = command.CreateParameter();
oracleDbType.SetValue(outCursor, oracleDbTypeRefCursor, null);
outCursor.Direction = detail.HasReturn ? ParameterDirection.ReturnValue : ParameterDirection.Output;
command.Parameters.Insert(0, outCursor);
}
#region IEmbeddedBatcherFactoryProvider Members
System.Type IEmbeddedBatcherFactoryProvider.BatcherFactoryClass
{
get { return typeof (OracleDataClientBatchingBatcherFactory); }
}
#endregion
}
エンドペースト-------