在.NET中引用正确版本的Oracle.DataAccess

时间:2017-01-10 14:57:54

标签: c# .net oracle dll reference

我试图从Visual Studio 2013上编写的.NET 4.0项目中引用Oracle.DataAccess。我的机器的GAC安装了两个版本的Oracle.DataAccess:4.112.1.2(由Oracle提供)版本11gr2)和4.121.2.0(由Oracle版本12c提供)。

我想引用版本4.112.1.2(我的项目必须在%ORACLE_HOME%设置为11gr2' s安装位置的情况下运行,并且引用4.121.2.0会导致运行时失败)。我的机器上没有管理员帐户,因此我无法卸载12c dll。

我已尝试以下步骤强制可执行文件在运行时加载4.112.1.2 dll:

  1. 使用强名称

    引用我的.csproj文件中的dll

    <Reference Include="Oracle.DataAccess, Version=4.112.1.2, Culture=neutral, PublicKeyToken=89b483f429c47342, processorArchitecture=x86"/>

  2. 更新我的App.Config文件以强制重定向:

  3. <dependentAssembly>
        <assemblyIdentity name="Oracle.DataAccess" publicKeyToken="89b483f429c47342" culture="neutral"/>
        <codeBase version="4.112.1.2" href="C:\Path\To\11gr2\Oracle.DataAccess.dll"/>
        <bindingRedirect oldVersion="4.121.2.0" newVersion="4.112.1.2"/>
        <publisherPolicy apply="no"/>
    </dependentAssembly>
    

    1. 我修改了我的PATH,以便在我的路径上首先制作11gr2客户端的bin目录:

      set PATH="C:\path\to\11gr2\BIN;%PATH%"

    2. 然而,无论我做什么,可执行文件都会在运行时从GAC加载4.121.2.0 dll。这是我附加调试器时的内容:

      'MyApp.exe' (Managed (4.0.30319)): Loaded 'C:\WINDOWS\Microsoft.Net\assembly\GAC_32\Oracle.DataAccess\v4.0_4.121.2.0_89b483f429c47342\Oracle.DataAccess.dll'
      

      我已阅读Microsoft关于程序集绑定的文档(herehere)。我还阅读了似乎与我的问题(herehere)相关的StackOverflow答案,但没有任何效果。

      如何强制.NET在运行时从GAC加载正确的DLL版本?

      编辑:

      Wernfried的回答让我觉得我可能会以错误的方式看待这个问题。这正是发生的事情:

      我使用ORACLE_HOME = C:\ ORACLE \ ora12c运行我的应用程序,一切正常(数据库访问成功,应用程序很满意)

      我使用ORACLE_HOME = C:\ ORACLE \ ora11gr2(所需版本)运行我的应用程序。应用程序崩溃,但有以下异常:

      Oracle.DataAccess.Client.OracleException ORA-12557: TNS:protocol adapter not loadable.
      <stacktrace follows>
      

      在堆栈跟踪之后,我发现在我的应用程序为创建数据库连接而进行的调用中发生了错误。我检查了我的连接字符串并验证它是否正确(并且它与12c成功的连接字符串相同)。然后我发现我调用的Oracle.DataAccess dll版本是12c版本,而不是11gr2版本。由此,我得出结论,我需要修改调用以将dll加载到&#34; force&#34; 11gr2一个。如果我咆哮错误的树,请告诉我!

2 个答案:

答案 0 :(得分:0)

据我所知,ODP.NET提供程序4.112.1.2仅适用于Oracle Client 11.2。 ODP.NET提供程序4.121.2.0需要Oracle 12.1客户端。

您的计算机上是否安装了两个版本的Oracle客户端?

要使用其中一个,您还必须相应地设置PATH环境变量。 PATH必须包含您希望在应用程序中使用的Oracle客户端二进制文件的文件夹。

注意,架构(即32位与64位)必须在您的应用程序,Oracle客户端和ODP.NET提供程序中完全相同。

但是你为什么要强制使用特定版本的ODP.NET?我建议使用此参考

<Reference Include="Oracle.DataAccess">
  <SpecificVersion>False</SpecificVersion>
  <Private>False</Private>
</Reference>

然后,无论您的计算机(或客户的计算机)上安装了什么,您的应用程序都会自动加载正确版本的ODP.NET。

无论如何,如果您想运行测试并强制使用特定版本的ODP.NET,您可以使用动态绑定。为此您的代码如下:

using (OracleConnection con = new OracleConnection(connString))
{
    con.Open();
    ...
}

必须像这样重写:

var DLL = default(Assembly);
DLL = Assembly.LoadFrom(@"C:\Path\To\11gr2\Oracle.DataAccess.dll");
// resp for GAC:
// DLL = Assembly.Load(String.Format("Oracle.DataAccess, Version={0}.{1}.*.*, Culture=neutral, PublicKeyToken=89b483f429c47342", 1, 112));    
var type = DLL.GetType("Oracle.DataAccess.Client.OracleConnection", true, false);
using ( dynamic con = Activator.CreateInstance(type, connString) ) {
    con.Open();
    ...
 }

答案 1 :(得分:0)

我相信我已经修好了。

让我工作的是取消设置ORACLE_HOME环境变量,并将C:\ Path \放到路径开头的\ 11gr2 \ bin中,如下所示:

set PATH=C:\Path\to\11gr2\bin;%PATH%