使用nhibernate和oracle使用DbProviderFactorys
在我们的系统中,我们使用nhibernate和Oracle。我们总是会遇到很多部署问题,因为Oracle.DataAccess.dll和安装在客户端服务器中的Oracle客户端之间的关系非常混乱 有时我们可以更改已安装的oracle客户端,有时则不能。有时我们需要32位版本的dll,有时需要64位版本的dll。我希望我能把oracle换成一个更友好的数据库,但现在这不是一个选项 消除所有这些混乱的一种方法是使用DbProviderFactorys,这样我就可以在项目中没有Oracle.DataAccess.dll的参考,而使用服务器上安装的任何版本 如何将nhibernate配置为使用DbProviderFactory 我的配置:使用nhibernate和oracle使用DbProviderFactorys,oracle,nhibernate,dbproviderfactories,Oracle,Nhibernate,Dbproviderfactories,在我们的系统中,我们使用nhibernate和Oracle。我们总是会遇到很多部署问题,因为Oracle.DataAccess.dll和安装在客户端服务器中的Oracle客户端之间的关系非常混乱 有时我们可以更改已安装的oracle客户端,有时则不能。有时我们需要32位版本的dll,有时需要64位版本的dll。我希望我能把oracle换成一个更友好的数据库,但现在这不是一个选项 消除所有这些混乱的一种方法是使用DbProviderFactorys,这样我就可以在项目中没有Oracle.DataA
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="dialect">NHibernate.Dialect.Oracle9iDialect</property>
<property name="connection.driver_class">NHibernate.Driver.OracleDataClientDriver</property>
<property name="connection.connection_string">Data Source=XE; User Id=*****; Password=******;</property>
<property name="current_session_context_class">NHibernate.Context.ManagedWebSessionContext, NHibernate</property>
<property name="sql_exception_converter">Way2Pim.Data.NHibernate.SqlExceptions.SqlExceptionConverter, Way2Pim.Data</property>
<property name="show_sql">true</property>
<property name="hbm2ddl.keywords">none</property>
<mapping assembly="MyAssembly" />
</session-factory>
</hibernate-configuration>
如果每次反射加载失败,NHibernate已经使用dbproviderfactory。请参阅NHibernate.Driver.ReflectionBasedDriver 此功能自
Revision: bb904343e18b693f6d1e13b357c305fdd46ff5ee
Author: Fabio Maulo
Date: 14.08.2010 19:37:12
Message:
Refactoring of ReflectionBasedDriver in order to use DbProviderFactories
明白了
Nhibernate有一个关于Oracle和DBProviderFactorys的bug。如果您查看OracleDataClientDriver类,它派生自ReflectionBasedDriver
在其构造函数中,ReflectionBasedDriver从DbProviderFactory正确加载Oracle.DataAccess提供程序。之后,OracleDataClientDriver构造函数尝试从加载的程序集获取OracleCommand类型,这当然会导致null,因为Oracle.DataAccess尚未在内存中
快速修复方法是创建自己的驱动程序,复制OracleDataClientDriver中的所有内容,但将其构造函数的所有行替换为以下内容:
System.Type oracleCommandType = base.CreateCommand().GetType();
oracleCommandBindByName = oracleCommandType.GetProperty("BindByName");
System.Type parameterType = oracleCommandType.Assembly.GetType("Oracle.DataAccess.Client.OracleParameter");
oracleDbType = parameterType.GetProperty("OracleDbType");
System.Type oracleDbTypeEnum = oracleCommandType.Assembly.GetType("Oracle.DataAccess.Client.OracleDbType");
oracleDbTypeRefCursor = System.Enum.Parse(oracleDbTypeEnum, "RefCursor");
就是这样,您的项目中不再有Oracle.DataAccess.dll:如果删除Oracle.DataAccess.dll,我会得到一个NullReferenceException