【问题标题】:Referencing the correct version of Oracle.DataAccess in .NET在 .NET 中引用正确版本的 Oracle.DataAccess
【发布时间】:2017-05-25 02:48:52
【问题描述】:

我正在尝试从使用 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 的安装位置的情况下运行,在这种情况下引用 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 文件以强制重定向:

<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%"

但是,无论我做什么,可执行文件都会在运行时从 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)。我还阅读了似乎与我的问题相关的 StackOverflow 答案(herehere),但没有任何效果。

如何强制 .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 以“强制”11gr2 之一。如果我找错树了,请告诉我!

【问题讨论】:

    标签: c# .net oracle dll reference


    【解决方案1】:

    据我所知,ODP.NET 提供程序 4.112.1.2 仅适用于 Oracle Client 11.2,resp。 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();
        ...
     }
    

    【讨论】:

    • 是的,我的机器上安装了两个客户端。我尝试在运行之前通过“set PATH="C:\Path\to\11gr2\bin;%PATH%" 手动将 11gr2 客户端放在我的路径上,但没有改变。我还尝试了您推荐的设置参考的方法项目,但没有改变。关于你关于不强制版本的评论,我已经用我试图确定的具体问题更新了我的问题
    • 把 'C:\Path\to\11gr2'' 放到你的 PATH 中
    【解决方案2】:

    我相信我已经修好了。

    对我有用的是取消设置 ORACLE_HOME 环境变量,并将 C:\Path\to\11gr2\bin 放在路径的开头,如下所示:

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

    【讨论】:

      猜你喜欢
      • 2013-12-10
      • 2011-03-14
      • 2010-09-07
      • 1970-01-01
      • 1970-01-01
      • 2010-12-06
      • 1970-01-01
      • 1970-01-01
      • 2020-05-10
      相关资源
      最近更新 更多