供应商与 Oracle 客户端版本不兼容。

171
我正在尝试将Oracle ODP.NET 11g (11.1.0.6.20) Instant Client作为数据提供程序在我的ASP.net项目中使用,但是当我运行aspx页面时,出现“提供程序与Oracle客户端版本不兼容”的错误信息。需要任何帮助。
我已经在Visual Studio 2005中引用了此数据提供程序,后台代码如下:
using Oracle.DataAccess.Client;
..

OracleConnection oOracleConn = new OracleConnection();
oOracleConn.ConnectionString =
    "Data Source=MyOracleServerName;" +
    "Integrated Security=SSPI";
oOracleConn.Open();

//Do Something

oOracleConn.Close();

页面出现的错误如下所示:
Exception Details: Oracle.DataAccess.Client.OracleException: The provider is not compatible with the version of Oracle client

Source Error: 
Line 21: 
Line 22: 
Line 23:             OracleConnection oOracleConn = new OracleConnection();
Line 24:             oOracleConn.ConnectionString =
Line 25:                 "Data Source=MyOracleServerName;" +

[OracleException (0x80004005): The provider is not compatible with the version of Oracle client]
   Oracle.DataAccess.Client.OracleInit.Initialize() +494
   Oracle.DataAccess.Client.OracleConnection..cctor() +483

Stack Trace: 
[TypeInitializationException: The type initializer for 'Oracle.DataAccess.Client.OracleConnection' threw an exception.]
   Oracle.DataAccess.Client.OracleConnection..ctor() +0
   Boeing.IVX.Web.RoyTesting.Page_Load(Object sender, EventArgs e) in C:\Documents and Settings\CE218C\Desktop\IVX.Net\Web\IVX\RoyTesting.aspx.cs:23
   System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +15
   System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +33
   System.Web.UI.Control.OnLoad(EventArgs e) +99
   System.Web.UI.Control.LoadRecursive() +47
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1436
28个回答

96

我进一步研究了这个问题,你只需要从下载的ODP.Net相同版本中获取所有适当的DLL文件,并将它们放在与你的Exe文件相同的文件夹中,因为ODP.Net不允许混合使用版本号。

我在这里解释了如何操作:http://splinter.com.au/using-the-new-odpnet-to-access-oracle-from-c 以下是要点:

  • 下载ODP.Net
  • 解压文件
  • 解压其中的所有JAR文件
  • 获取刚刚解压出的这些dll文件:
    • oci.dll (重命名自 'oci.dll.dbl')
    • Oracle.DataAccess.dll
    • oraociicus11.dll
    • OraOps11w.dll
    • orannzsbb11.dll
    • oraocci11.dll
    • ociw32.dll (重命名自 'ociw32.dll.dbl')
  • 将所有DLL文件放在与您的C#可执行文件相同的文件夹中

4
你的解决方案对我非常有效 - 在找到这个之前,我先看了你的博客文章。你太厉害了。谢谢! :-) 另外,使用最新版本的ODAC,我不需要解压任何JAR文件... .dll文件位于我的Oracle Home中的各个目录中。一个简单的Windows搜索很快就能找到它们。 - Pandincus
11
另外,我在我的开发机上使用了最新版本的ODAC(11.2.0.1.2),而且我只需要以下这些文件:oci.dll、Oracle.DataAccess.dll、oraociei11.dll和OraOps11w.dll。正如Chris指出的那样,请确保它们和你的可执行文件在同一个文件夹中。;-) - Pandincus
1
听起来新版本更容易找到dll文件。太好了!现在等Oracle把它们合并成一个简单的dll需要多长时间... - Chris
1
如果可以的话,现在你应该使用C#托管驱动程序 :) - Chris
1
如果您的客户已经安装了(标准的)Oracle客户端,那么这个解决方案可能会失败,因为Oracle.DataAccess.dll已经被安装在GAC中。在这种情况下, Oracle.DataAccess.dll将从 GAC 中获取(优先于.exe文件夹),但其他DLL文件将从.exe文件夹中获取。这可能会导致“版本不兼容”的错误。 - Wernfried Domscheit
显示剩余9条评论

52

首先,您应该“忽略”所有关于x86 / x64的讨论,而是尝试使用ODP.NET托管驱动程序(如果您正在使用.Net v4+):

https://www.nuget.org/packages/Oracle.ManagedDataAccess/

https://www.nuget.org/packages/Oracle.ManagedDataAccess.EntityFramework/

Oracle ODP.net托管与非托管驱动

避免所有“非托管”DLL和架构问题!:D (Oracle终于意识到了)。

NuGet包(适用于11g):

enter image description here

旧/手动方法:

有关如何转换为使用托管库的信息:

  • 首先,这里有一个很好的代码比较:托管 vs 非托管http://docs.oracle.com/cd/E51173_01/win.122/e17732/intro005.htm#ODPNT148
  • 确保您已下载了ODP.NET,仅限托管驱动程序Xcopy版本
  • 从下载的zip文件中,将以下内容复制并粘贴到您的项目目录中:
    • Oracle.ManagedDataAccessDTC.dll
    • Oracle.ManagedDataAccess.dll
  • 添加对Oracle.ManagedDataAccess.dll的引用
  • 确保您的exe已发布(在VS2010中添加到应用程序文件夹),包括两个dlls

3
Oracle终于推出了完全托管的驱动程序,这是个好消息。携带那个100MB的dll一直是个真正的负担。 - Jafin
1
托管驱动程序对我非常好用 - 自从使用它以来,我没有遇到过任何问题/您可以将项目设置回 AnyCPU 等,它可以很好地工作 :) - Tod Thomson
5
请注意,虽然托管服务提供商不错,但缺乏许多完整服务提供商所具备的功能,尤其是Oracle内置的加密功能。 - Justin Skiles
1
Oracle的文档往往是“分散的”,至少可以这么说。这里有一个关于一些不受支持的方法的好链接。此外,驱动程序本身附带了一个readme,概述了一些限制。 - Justin Skiles
2
使用托管驱动程序是最终解决方案!每当我想到我因类型不匹配而花费的所有时间时,我都会做噩梦。 - ettore ct
显示剩余4条评论

37

我只安装了Oracle Data Provider for .NET 2.0 (11.1.0.6.20),没有安装Oracle Instant Client (11.1.0.6.0)

我刚刚安装了它,错误消失了!


4
你能否将这4个即时客户端DLL文件简单地复制到与你的EXE相同的文件夹中,而不是安装客户端呢?(这些文件是:oci.dll、orannzsbb11.dll、oraocci11.dll、oraociicus11.dll) - Chris
3
@Chris:是的,你可以。根据我的经验,你需要 oci.dll、orannzsbb11.dll、oraociicus11.dll、oraops11w.dll 和 oracle.dataaccess.dll。 - Pakman
1
对我来说是相反的 - 我安装了客户端,但没有安装提供者。 - Ev.

33

这可能是因为使用64位.NET运行时来运行32位Oracle客户端引起的。如果您运行应用程序的服务器是64位的,那么就会发生这种情况。它将使用64位运行时来运行.NET应用程序。您可以在VS中为项目设置CPU标志以在32位运行时中运行。


刚遇到这个问题。在一个(32位)测试应用程序中运行良好,但在IIS中出现错误。我没有要求所有涉及的程序集都是32位,而是改为使用32位AppPool。 - anton.burger

29

让我们做一个总结:

错误信息"The provider is not compatible with the version of Oracle client"可能有多个原因导致。同时,错误信息可能有不同的类型,例如"Object reference not set to an instance of an object.""Could not load file or assembly 'Oracle.DataAccess,' or one of its dependencies"

  • 你没有安装Oracle客户端。在这种情况下,错误信息确实会误导。

Oracle Data Provider for .NET (ODP.NET,即文件Oracle.DataAccess.dll)未包含在Oracle Instant Client中,必须单独安装(从32位 Oracle 数据库访问组件(ODAC)64位 Oracle 数据库访问组件(ODAC)下载),或者您必须在Oracle Universal Installer(OUI)中选择相应选项。

请注意,在安装Oracle Data Provider>=12.1时,提供程序不会自动注册到GAC中。如果需要,请手动注册,参见Oracle Doc 2272241.1

  • ODP.NET的版本与安装的Oracle Client版本不匹配。您必须检查甚至是小版本号!例如,Oracle.DataAccess.dll版本4.112.3.0与Oracle Client11.2.0.4不兼容。仔细检查ODP.NET和Oracle Client的版本。您可以在oraociei*.dll和/或OraOps*w.dll上使用sigcheck来获取Oracle Client的版本。

    请注意不同的编号方案。文件版本4.112.3.0表示:.NET Framework Version 4, Oracle Release 11.2.0.3.x

    有ODP.NET版本“1.x”,“2.x”和“4.x”。这些数字与Microsoft .NET Framework版本1.0.3705/1.1.4322、2.0.50727和4.0.30319相关。版本“1.x”可用直到Oracle Client 11.1。版本“4.x”从Oracle Client 11.2开始引入

  • ODP.NET的架构(32位或64位)与您的应用程序架构不匹配。 32位应用程序仅适用于32位Oracle Client / ODP.NET,而64位应用程序则需要64位Oracle Client / ODP.NET。(除非您使用ODP.NET Managed Driver

    .NET Framework版本不匹配。例如,如果您使用Target .NET Framework 2.0编译应用程序,则无法使用ODP.NET版本4.x。.NET Framework目标版本必须等于或高于ODP.NET版本。

    在您的开发计算机上(即编译时加载的版本),Oracle.DataAccess.dll的版本高于目标计算机上的版本。

    请注意,Oracle.DataAccess.dll可能会从GAC加载,该加载方式默认优先于任何本地提供的文件。

    新版的ODP.NET需要更高版本的Microsoft .NET Framework。例如,ODP.NET版本21.4需要.NET Framework 4.8。请检查您发布的 "Data Provider for .NET Developer's Guide"中的系统要求。

    解决方案

    考虑使用ODP.NET Managed Driver,可以从Oracle页面下载:64-bit Oracle Data Access Components (ODAC) Downloads。在那里,您只需将Oracle.ManagedDataAccess.dll文件复制到应用程序目录中,无需其他操作即可使用。它适用于32位和64位。

    在您的*.csproj,或*.vbproj中,编辑对ODP.NET的引用,如下所示:

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

Attributes like Version=... or processorArchitecture=... are not required. It is expected that the correct Oracle.DataAccess.dll will be loaded for your application based on the selected architecture and target .NET framework, assuming it has been installed properly (though this is not 100% verified).

  • If you are unsure of the version of Oracle Client on the target machine (e.g. if it belongs to a customer), you can download the least XCopy version of Oracle Data Access Components from the aforementioned download page. Extract the zip file and copy only the Oracle.DataAccess.dll file to your local machine. In your VS project, make a reference to this DLL (which may be outdated), and note that the version of this DLL is the least version of ODP.NET that your application will work with. When you run your application, the Publisher Policy in GAC will redirect to the actually installed version.

  • It is not wise to take individual DLLs and copy them to specific folders, as there is a high risk of version mismatch if the target machine has any installed Oracle products. To avoid this issue, it is recommended to uninstall all Oracle products from your machine and perform a fresh installation. Refer to How to uninstall / completely remove Oracle 11g (client)? to ensure that your machine is truly clean.

  • If you need to work with both 32-bit and 64-bit applications simultaneously, follow these steps to install both versions on one machine:

Assumptions: Oracle Home is called OraClient11g_home1, Client Version is 11gR2.

  • Optionally remove any installed Oracle client

  • Download and install the Oracle x86 Client into a folder such as C:\Oracle\11.2\Client_x86.

  • Download and install the Oracle x64 Client into a different folder, such as C:\Oracle\11.2\Client_x64.

  • Open a command line tool, navigate to the %WINDIR%\System32 folder (usually C:\Windows\System32), and create a symbolic link named ora112 that points to the C:\Oracle\11.2\Client_x64 folder (see below).

  • Navigate to the %WINDIR%\SysWOW64 folder (usually C:\Windows\SysWOW64) and create a symbolic link named ora112 that points to the C:\Oracle\11.2\Client_x86 folder (see below).

修改 PATH 环境变量,将所有类似于 C:\Oracle\11.2\Client_x86C:\Oracle\11.2\Client_x64 的条目替换为 C:\Windows\System32\ora112,同时将它们的 \bin 子文件夹也替换。注意: C:\Windows\SysWOW64\ora112 不应该在 PATH 环境中。

如果需要,可以将你的 ORACLE_HOME 环境变量设置为 C:\Windows\System32\ora112

打开你的注册表编辑器。将注册表值 HKLM\Software\ORACLE\KEY_OraClient11g_home1\ORACLE_HOME 设置为 C:\Windows\System32\ora112

将注册表值 HKLM\Software\Wow6432Node\ORACLE\KEY_OraClient11g_home1\ORACLE_HOME 设置为 C:\Windows\System32\ora112(而不是 C:\Windows\SysWOW64\ora112)。

完成!现在你可以无缝地使用 x86 和 x64 Oracle 客户端,即一个 x86 应用程序将加载 x86 库,一个 x64 应用程序将加载 x64 库,无需对你的系统进行任何其他修改。

创建符号链接的命令:

cd C:\Windows\System32
mklink /d ora112 C:\Oracle\11.2\Client_x64
cd C:\Windows\SysWOW64
mklink /d ora112 C:\Oracle\11.2\Client_x86

注意事项:

  • 两个符号链接的名称必须相同,例如ora112

  • 如果您想手动安装ODP.NET,请注意选择适当的安装文件夹。

  • 尽管名称如此,文件夹C:\Windows\System32包含x64库,而C:\Windows\SysWOW64包含x86(32位)库。不要混淆。

  • 也许将您的TNS_ADMIN环境变量(或注册表中的TNS_ADMIN条目)设置为一个公共位置是个明智的选择,例如 TNS_ADMIN=C:\Oracle\Common\network


这个IMO(指 in my opinion)比实际答案更有价值。所以,如果我有一个针对 .net 4 的 x86 应用程序,而数据库版本是 9i,那么如果用户使用 32 位或 64 位 Windows,他们需要哪个客户端版本?Oracle 表示任何客户端版本都与任何 db 版本兼容。答案是:32 位用户安装 32 位版本,64 位用户安装 64 位版本,并使用 ODP.NET 管理驱动程序来确定它正在与哪个操作系统通信? - Luminous
2
当您使用ODP.NET托管驱动程序时,无需安装任何Oracle客户端-这是它的主要优点。它适用于x86和x64应用程序。如果没有“ODP.NET托管驱动程序”,则x86应用程序还需要x86(即32位)Oracle客户端,无论数据库服务器架构如何。 - Wernfried Domscheit
我刚遇到了“需要安装Microsoft Visual C++ 2010 Redistributable” - 你应该将其添加到你的摘要中。 - Jay Sullivan
1
我认为这个错误与Oracle或ODP.NET无关或不是由它们引起的。 - Wernfried Domscheit
@BN,是的,你说得对。然而,ODP.NET管理驱动程序的限制不是这里讨论的话题。还请参阅ODP.NET托管驱动程序和非托管驱动程序之间的差异ODP.NET托管驱动程序与ODP.NET非托管驱动程序之间的配置差异 - Wernfried Domscheit
显示剩余2条评论

7
经过数小时的故障排除,我发现这个问题是由于在我的项目bin目录中有Oracle.DataAccess.dll(v4.0),但运行时也从GAC加载了Oracle.DataAccess.dll(v2.x)所致。在项目引用中删除和重新添加Oracle.DataAccess条目解决了我的问题。
在我的情况下,这里提到的其他文件似乎不是必需的。
更新
“提供程序与Oracle客户端版本不兼容”的根本原因(通常)是托管程序集试图加载不匹配版本的非托管库。似乎您可以通过在web.config中指定库路径来强制Oracle驱动程序使用正确的库。1
<configuration>
  <oracle.dataaccess.client>
    <settings>
      <add name="DllPath" value="C:\oracle\bin"/>
      <!-- ... -->
    </settings>
  </oracle.dataaccess.client>
</configuration>

谢谢!你的解决方案给了我灵感,经过两天的努力(我使用的是Visual Studio 2010 Net 4和Oracle 10g客户端)...我看到了GAC,当然我已经安装了3个版本的Oracle.DataAccess.dll,我卸载了所有的版本(并删除了"DbProviderFactories"中无效的machine.config键),然后重新安装了ODAC1120320 x64。现在它可以正常工作了。 - Hernaldo Gonzalez

6

在目标机器上安装 ODP.Net 应该就能解决问题...复制 dll 文件似乎不是一个好主意...


6

对于Oracle 11g(11.1.0.7.20),我需要将以下dll文件与我的Exe文件一起添加以使其正常工作。

  1. oci.dll
  2. OraOps11w.dll
  3. oraociicus11.dll(相当庞大,接近30mb)
  4. Oracle.DataAccess.dll

你想说的是130 MB。 - Elmue

3

我有同样的问题,但在我的情况下,我不能只是将dll文件复制到bin文件夹中,然后只能“重新绑定”程序集版本。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <runtime>    
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Oracle.DataAccess" publicKeyToken="89B483F429C47342" culture="neutral"/>
        <bindingRedirect oldVersion="2.112.2.0" newVersion="2.112.1.0"/>
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

3
这是我为解决持续三个小时的问题所做的事情:
1. 在Oracle主目录下,即C:\oracle\product\11.2.0,我有一个名为client_1的文件夹,之前安装了Windows 64位的ODP.NET组件。
2. 后来,当我尝试通过Visual Studio 2012调试我的ASP.NET Web API应用程序时,一直收到此错误消息:"提供程序与Oracle客户端版本不兼容"。
3. 通过搜索Google,我发现这是因为我正在使用ODP.NET 64位。然后我下载了Windows 32位的ODP.NET并进行了安装,但仍然收到相同的错误消息。
4. 解决方案:删除client_1文件夹,并重新安装ODP.NET 32位。某种程度上,安装程序会将64位版本和32位版本混合在一起。想象一下...
5. 现在我又快乐了,能够打开新的OracleConnection连接。终于! :)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接