1

在我们的系统中,我们使用的是 nhibernate 和 Oracle。我们总是遇到很多部署问题,因为 Oracle.DataAccess.dll 和安装在我们客户端服务器中的 Oracle 客户端之间的关系是一团糟。

有时我们可以更改已安装的 oracle 客户端,有时则不能。有时我们需要 32 位版本的 dll,有时需要 64 位版本。我希望我可以更改 oracle 以获得更友好的数据库,但目前这不是一个选择。

摆脱所有这些混乱的一种方法是使用 DbProviderFactories,因此我的项目中没有 Oracle.DataAccess.dll 的引用,而使用服务器上安装的任何版本。

如何配置 nhibernate 以使用 DbProviderFactory?

我的配置:

<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>
4

2 回答 2

0

NHibernate already uses the dbproviderfactory if loading per reflection fails. see NHibernate.Driver.ReflectionBasedDriver

this feature is available since

Revision: bb904343e18b693f6d1e13b357c305fdd46ff5ee
Author: Fabio Maulo
Date: 14.08.2010 19:37:12
Message:
Refactoring of ReflectionBasedDriver in order to use DbProviderFactories
于 2012-05-08T07:29:57.050 回答
0

知道了!

Nhibernate 有一个关于 Oracle 和 DBProviderFactories 的错误。如果您查看 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 :)

于 2012-05-08T20:49:14.130 回答