C# NHibernate-针对XmlType的Oracle 11g配置
我试图让NHibernate使用Oracle 11g的XmlType 将引发以下异常:C# NHibernate-针对XmlType的Oracle 11g配置,c#,nhibernate,configuration,xmltype,C#,Nhibernate,Configuration,Xmltype,我试图让NHibernate使用Oracle 11g的XmlType 将引发以下异常: Dialect does not support DbType.Xml 我的配置如下所示: <?xml version="1.0" encoding="utf-8" ?> <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2"> <session-factory> <proper
Dialect does not support DbType.Xml
我的配置如下所示:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="dialect">NHibernate.Dialect.Oracle10gDialect</property>
<property name="connection.driver_class">NHibernate.Driver.OracleClientDriver</property>
<property name="connection.connection_string">...</property>
<property name="show_sql">false</property>
</session-factory>
</hibernate-configuration>
映射文件的重要部分:
<property name="History" />
尝试使用自定义Oracle数据客户端驱动程序,以下是代码:
using System;
using System.Data;
using System.Data.Common;
using System.Reflection;
using NHibernate;
using NHibernate.AdoNet;
using NHibernate.Driver;
using NHibernate.Engine.Query;
using NHibernate.SqlTypes;
using NHibernate.Util;
using Oracle.DataAccess.Client;
/// <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 CustomOracleDataClientDriver : 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 CustomOracleDataClientDriver()
: base(
DriverAssemblyName,
ConnectionTypeName,
CommandTypeName) {
var parameterType = ReflectHelper.TypeFromAssembly("Oracle.DataAccess.Client.OracleParameter",
DriverAssemblyName, false);
this.oracleDbType = parameterType.GetProperty("OracleDbType");
var oracleDbTypeEnum = ReflectHelper.TypeFromAssembly("Oracle.DataAccess.Client.OracleDbType",
DriverAssemblyName, false);
this.oracleDbTypeRefCursor = Enum.Parse(oracleDbTypeEnum, "RefCursor");
this.oracleDbTypeXmlType = 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 ":"; }
}
#region IEmbeddedBatcherFactoryProvider Members
Type IEmbeddedBatcherFactoryProvider.BatcherFactoryClass {
get { return typeof (OracleDataClientBatchingBatcherFactory); }
}
#endregion
/// <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 = this.FormatNameForParameter(name);
this.oracleDbType.SetValue(dbParam, this.oracleDbTypeXmlType, null);
break;
default:
base.InitializeParameter(dbParam, name, sqlType);
break;
}
}
protected override void OnBeforePrepare(IDbCommand command) {
base.OnBeforePrepare(command);
((OracleCommand) command).BindByName = true;
var detail = CallableParser.Parse(command.CommandText);
if (!detail.IsCallable)
return;
command.CommandType = CommandType.StoredProcedure;
command.CommandText = detail.FunctionName;
var outCursor = command.CreateParameter();
this.oracleDbType.SetValue(outCursor, this.oracleDbTypeRefCursor, null);
outCursor.Direction = detail.HasReturn ? ParameterDirection.ReturnValue : ParameterDirection.Output;
command.Parameters.Insert(0, outCursor);
}
}
使用系统;
使用系统数据;
使用System.Data.Common;
运用系统反思;
使用NHibernate;
使用NHibernate.AdoNet;
使用NHibernate.Driver;
使用NHibernate.Engine.Query;
使用NHibernate.SqlTypes;
使用NHibernate.Util;
使用Oracle.DataAccess.Client;
///
///用于使用Oracle.DataAccess数据提供程序的NHibernate驱动程序
///
///
///代码是由在NHibernate论坛上发表的。
///
公共类CustomOracleDataClientDriver:ReflectionBasedDriver,IEmbeddedBatcherFactoryProvider{
private const string driversassemblyname=“Oracle.DataAccess”;
private const string ConnectionTypeName=“Oracle.DataAccess.Client.OracleConnection”;
private const string CommandTypeName=“Oracle.DataAccess.Client.OracleCommand”;
私有静态只读SqlType GuidSqlType=newsqltype(DbType.Binary,16);
私有只读属性信息oracleDbType;
私有只读对象oracleDbTypeRefCursor;
私有只读对象oracleDbTypeXmlType;
///
///初始化的新实例。
///
///当
///Oracle.DataAccess
///无法加载程序集。
公共CustomOracleDataClientDriver()
:基本(
DriverRassemblyName,
ConnectionTypeName,
命令类型(名称){
var parameterType=ReflectHelper.TypeFromAssembly(“Oracle.DataAccess.Client.OracleParameter”,
DriverAssemblyName,false);
this.oracleDbType=parameterType.GetProperty(“oracleDbType”);
var oracleDbTypeEnum=ReflectHelper.TypeFromAssembly(“Oracle.DataAccess.Client.OracleDbType”,
DriverAssemblyName,false);
this.oracleDbTypeRefCursor=Enum.Parse(oracleDbTypeEnum,“RefCursor”);
this.oracledbypexmltype=Enum.Parse(oracledbypeenum,“XmlType”);
}
///
///
公共重写bool UseNamedPrefixInSql{
获取{return true;}
}
///
///
公共覆盖布尔UseNamedPrefixin参数{
获取{return true;}
}
///
///
公共重写字符串NamedPrefix{
获取{return”:“;}
}
#区域IEMBedBatcherFactoryProvider成员
类型IEMBededBatcherFactoryProvider.BatcherFactoryClass{
获取{返回类型(OracleDataClientBatchingBatcherFactory);}
}
#端区
///
///这将添加逻辑以确保不会创建DbType.Boolean参数,因为ODP.NET不支持它。
///
受保护的重写void InitializeParameter(IDbDataParameter dbParam,字符串名称,SqlType SqlType){
//如果传入的参数包含布尔值,则需要对其进行转换
//由于ODP.NET不支持DbType.Boolean,因此无法转换为其他类型
开关(sqlType.DbType){
case DbType.Boolean:
InitializeParameter(dbParam,name,SqlTypeFactory.Int16);
打破
案例DbType.Guid:
InitializeParameter(dbParam、name、GuidSqlType);
打破
case DbType.Xml:
dbParam.ParameterName=此.FormatNameForParameter(名称);
this.oracleDbType.SetValue(dbParam,this.oracleDbTypeXmlType,null);
打破
违约:
InitializeParameter(dbParam,name,sqlType);
打破
}
}
受保护的覆盖无效OnBeforePrepare(IDbCommand){
base.onbefore准备(命令);
((OracleCommand)命令).BindByName=true;
var detail=CallableParser.Parse(command.CommandText);
如果(!detail.IsCallable)
返回;
command.CommandType=CommandType.storedProcess;
command.CommandText=detail.FunctionName;
var outCursor=command.CreateParameter();
this.oracleDbType.SetValue(outCursor,this.oracleDbTypeRefCursor,null);
outCursor.Direction=detail.HasReturn?ParameterDirection.ReturnValue:ParameterDirection.Output;
command.Parameters.Insert(0,outCursor);
}
}
NHibernate配置:
...
<property name="connection.driver_class">
Your.NameSpace.CustomOracleDataClientDriver, Your.Assembly.Name
</property>
<property name="dialect">
NHibernate.Dialect.Oracle10gDialect
</property>
...
。。。
Your.NameSpace.CustomOracleDataClientDriver,Your.Assembly.Name
NHibernate.方言
...
下面是一个示例,在该示例中,我可以找到ExecuteType或IDbProfiler类吗?@Daffi,您的XmlType属性映射是什么?您可以尝试在映射中指定sql类型(参见要点),我刚刚测试过,它对我有效(.NET 4.0,Oracle.DataAccess v4.112.3.0),这是完整的源代码,我和你一样做了sam,现在我得到了一个例外:未知标识符。我想这是因为我的Oracle.DataAccess版本是:2.112.1.0。。。但我还是希望.NET4.0的版本…它终于成功了。我仍在使用旧的DataAccess版本,我的问题是名称错误的列(日期=保留!)
...
<property name="connection.driver_class">
Your.NameSpace.CustomOracleDataClientDriver, Your.Assembly.Name
</property>
<property name="dialect">
NHibernate.Dialect.Oracle10gDialect
</property>
...