提供程序与Oracle客户端的版本不兼容

我试图在我的ASP.net项目上使用Oracle ODP.NET 11g(11.1.0.6.20)即时客户端作为数据提供者,但是当我运行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 

我一直在进一步研究这个问题,你只需要从相同的下载版本的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#可执行文件相同的文件夹中

对于初学者,您应该“忽略”所有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):

在这里输入图像描述

旧的/手动的方法:

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

  • 首先,这里是托管非托管的很好的代码比较: 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中的应用程序文件夹 )与这两个DLL

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

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

这可能是由于针对32位Oracle客户端运行64位.NET运行时造成的。 如果您的服务器在64位上运行应用程序,则可能发生这种情况。 它将使用64位运行时运行.NET应用程序。 您可以在VS的项目中设置CPU标志以在32位运行时运行。

我们来尝试做一些总结:

错误消息“提供程序与Oracle客户端的版本不兼容”可能由几个原因引起。

  • “Oracle数据提供程序的.NET”(ODP.NET)根本没有安装。 在这种情况下,错误信息确实是误导性的。

    ODP.NET不包含在Oracle Instant Client中,必须手动安装(从32位Oracle数据访问组件(ODAC)或64位Oracle数据访问组件(ODAC)下载下载 ),或者必须根据选项在Oracle Universal Installer(OUI)中。

  • ODP.NET的体系结构(32位或64位)与您的应用程序体系结构不匹配。 32位应用程序只适用于32位Oracle Client / ODP.NET,64位应用程序需要64位Oracle Client / ODP.NET。 (除非您使用ODP.NET托管驱动程序

  • Oracle.DataAccess版本与Oracle Client的已安装版本或/和.NET的目标Framework不匹配。

    Oracle.DataAccess.dll版本“2. 112 .1.0”表示“.NET Framework版本2”,“Oracle版本11.2 ”等。

    有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客户端11.1之前可用。 Oracle Client 11.2引入了版本“4.x”

    示例:在编译选项中将目标设置为.NET Framework 4时,还必须安装ODP.NET 4.x版。 (如果使用后期绑定,则可以绕过此限制。)ODP.NET版本x.112仅适用于Oracle Client版本11.2。

    我没有测试每个可能的组合,也许有一些上下兼容性和一些组合。

解决方案

  • 考虑使用ODP.NET托管驱动程序,它可以从Oracle页面下载: 64位Oracle数据访问组件(ODAC)下载 。 在那里,你只需要复制Oracle.ManagedDataAccess.dll文件到你的应用程序目录中,不需要其他东西。 它适用于32位和64位。

  • 在你的*.csproj ,resp。 *.vbproj编辑你的参考ODP.NET是这样的:

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

    Version=...processorArchitecture=...这样的属性不是必需的。 您的应用程序将加载正确的Oracle.DataAccess.dll具体取决于所选的体系结构和目标.NET框架(前提是它已正确安装)

  • 我不认为这是一个明智的方法来抓取单个DLL并将其复制到某些文件夹。 从您的机器上卸载任何Oracle客户端,并考虑以上几点重新安装。

  • 如果您必须同时使用32位和64位应用程序,请按照此说明在一台机器上安装两个版本:

假设:Oracle Home被称为OraClient11g_home1 ,客户端版本是11gR2。

  • 可以选择删除已安装的Oracle客户端

  • 下载并安装Oracle x86 Client,例如到C:\Oracle\11.2\Client_x86

  • 将Oracle x64 Client下载并安装到不同的文件夹,例如C:\Oracle\11.2\Client_x64

  • 打开命令行工具,进入文件夹%WINDIR%\ System32,通常是C:\Windows\System32并创建一个符号链接ora112到文件夹C:\Oracle\11.2\Client_x64 (见下文)

  • 切换到文件夹%WINDIR%\ SysWOW64,通常是C:\Windows\SysWOW64并创建一个符号链接ora112到文件夹C:\Oracle\11.2\Client_x86 (见下文)

  • 修改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_HOMEC:\Windows\System32\ora112

  • 将注册表值HKLM\Software\Wow6432Node\ORACLE\KEY_OraClient11g_home1\ORACLE_HOMEC:\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

对于Oracle 11g(11.1.0.7.20),我必须添加下面的DLL以及我的EXE才能工作。

  1. OCI.DLL
  2. OraOps11w.dll
  3. oraociicus11.dll(相当大的接近30mb)
  4. Oracle.DataAccess.dll

经过几个小时的故障排除之后,我发现这个问题是由我的项目bin目录中有Oracle.DataAccess.dll(v4.0)引起的,但运行时也从GAC加载了Oracle.DataAccess.dll(v2.x)。 删除和读取项目引用中的Oracle.DataAccess条目解决了我的问题。

在这里提到的其他文件似乎没有必要在我的情况。

UPDATE

“提供程序与Oracle客户端版本不兼容”错误的根本原因是(通常)托管程序集尝试加载与版本不匹配的非托管库。 看来你可以通过在web.config中指定库路径来强制Oracle驱动程序使用正确的库

 <configuration> <oracle.dataaccess.client> <settings> <add name="DllPath" value="C:\oracle\bin"/> <!-- ... --> </settings> </oracle.dataaccess.client> </configuration> 

在目标机器上安装ODP.Net,它应该解决这个问题…复制DLL的看起来不是一个好主意…

浪费了三个小时后,我的问题就是:

缺少OraOps11w.dll

为什么要生成“提供程序与Oracle客户端的版本不兼容”错误消息? 它必须是由Oracle编码/测试差。 自从1994年以来,我一直使用Oracle,自2002年以来,我们多次使用.Net,这实际上总是一种痛苦。

每个人都应该卸载Oracle,并按照上面的克里斯的解决方案(最佳答案) 。 这应该每次都有效

从StackOverflow的另一篇文章,这是如何卸载Oracle(忘记Oracle卸载工具,因为它不能正常工作):

  • 使用Oracle Universal Installer(OUI)卸载所有Oracle组件。
  • 运行regedit.exe并删除HKEY_LOCAL_MACHINE / SOFTWARE / ORACLE项。 这包含所有Oracle产品的注册表条目。
  • 删除在注册表的以下部分留下的对Oracle服务的任何引用:HKEY_LOCAL_MACHINE / SYSTEM / CurrentControlSet / Services / Ora *哪些与Oracle相关应该是非常明显的。
  • 重新启动你的机器。
  • 删除“C:\ Oracle”目录,或者任何目录是你的ORACLE_BASE。
  • 删除“C:\ Program Files \ Oracle”目录。
  • 清空“c:\ temp”目录中的内容。
  • 清空回收站。

Chris比我在Server 2003(32位)上的dll少 。 这是我的:

 C:\oracle\instantclient>dir /b oci.dll ociw32.dll Oracle.DataAccess.dll orannzsbb11.dll oraocci11.dll oraociei11.dll OraOps11w.dll Orasqlplusic11.dll sqlplus.exe tnsnames.ora 

C:\ oracle \ instantclient是在全局路径和ORACLE_HOME环境变量中。 .Net代码引用C:\ oracle \ instantclient \ Oracle.DataAccess.dll

在我看来,虽然你有Oracle Istant Client的ODP,但ODP可能会尝试使用实际的Oracle Client。 你在机器上是否安装了标准的Oracle客户端? 我记得甲骨文在同一台机器上的多个客户端时相当挑剔。

我有完全相同的问题。 我编译应用程序后删除(忘记我已经删除)oraociei11.dll。 它试图执行时发生这个错误。 所以当它无法找到该DLL,oraociei11.dll,它显示这个错误。 当出现这个错误时,可能会有其他的情况,但这似乎是其中之一。

另外找IIS应用程序池启用32位的true或false标志,当你看到这个消息的时候,一些oracle论坛指示我这个!

以下是我所做的解决这个持续3个小时的问题:

  1. 在位于C:\oracle\product\11.2.0 Oracle主目录下,我有一个名为client_1的文件夹,我之前安装了用于Windows 64位的ODP.NET位。

  2. 后来在尝试使用Visual Studio 2012调试我的ASP.NET Web API应用程序时,我不断收到此错误消息: 提供程序与Oracle客户端的版本不兼容

  3. 搜索谷歌我发现这是因为我使用ODP.NET 64位。 然后我抓住Windows的ODP.NET 32位,并安装它,但我一直得到相同的错误信息。

  4. 解决方案:删除文件夹client_1和resinstalled ODP.NET 32位。 有些安装程序混合64位版本和32位版本的位。 去搞清楚…

  5. 现在我很高兴,我可以打开一个新的OracleConnection 。 最后! 🙂

对于任何人仍然有这个问题:基于这篇文章

http://oradim.blogspot.com/2009/09/odpnet-provider-is-not-compatible-with.html

我发现我的服务器缺少Microsoft C ++ Visual Runtime Library – 由于安装了Visual Studio,我在开发机器上安装了它。 我从这里下载并安装了(当前)最新版本的库:

http://www.microsoft.com/en-us/download/details.aspx?id=13523

从C#设置和甲骨文的呼吁做了!

IIS / IWAM用户是否具有Oracle目录的权限? 你可以连接到这个数据源使用另一个应用程序,如Excel或Access?

我们遇到了同样的问题,因为网络共享上的Oracle.Data.dll程序集是由我们的DBA更新的。 从项目中删除参考,并再次添加解决了这个问题。

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

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

只需两个步骤来解决这个问题。

  1. 进入应用程序池的设置并将“启用32位应用程序”标志设置为True。
  2. 确保您的Bin中的所有Dll现在是32位版本…

祝你好运。

我没有走上获取新DLL的道路。 我们有一大堆现有的项目工作得很好,只是我的新项目让我感到头疼,所以我决定尝试一些其他的东西。

我的项目是使用内部开发的Internal.dll,依赖于Oracle.DataAccess.dll v4.112.3.0 。 出于某种原因,发布时,Visual Studio总是上传v4.121.0.0 ,即使它没有在任何配置文件中明确指定。 这就是为什么我得到一个错误。

所以我做的是:

  1. 从一个成功运行的项目复制Internal.dll到我的网站的/bin (只是为了安全起见)。
  2. 从其中一个成功运行的项目复制Oracle.DataAccess.dll到我的网站的/bin
  3. 从我的网站添加引用到他们两个。
  4. 最后在myWebSite.csproj显示了Oracle.DataAccess参考,但它显示了错误的版本: v4.121.0.0而不是v4.112.3.0
  5. 我手动更改了myWebSite.csproj的引用,现在它读取:

     <Reference Include="Oracle.DataAccess, Version=4.112.3.0, Culture=neutral, PublicKeyToken=89b483f429c47342, processorArchitecture=x86"> <SpecificVersion>False</SpecificVersion> <HintPath>bin\Oracle.DataAccess.dll</HintPath> </Reference> 

TLDR版本:

  • 改为使用12c 100%托管提供程序 。
  • 如果您必须使用旧的提供程序,则需要将Oracle.DataAccess.dll指向正确版本的非托管Oracle Client Dll。 如果您的计算机上安装了多个Oracle客户端,可能很简单,因为在您的应用程序配置中包括“DllPath”配置变量(请参见下文),但是您可能还需要安装新的Oracle客户端以指向它。

完整版:

首先,让我们确保我们了解旧援助提供者的组件(不是新的12c 100%托管提供者)。 它由两部分组成:

  1. 受管.net组件 – Oracle.DataAccess.dll
  2. 非托管(非.NET)客户端

简单地说,Oracle.DataAccess.dll几乎只是一个包装器,将.net指令翻译成非托管客户端的ORACLE-NET指令。

也就是说,当您加载Oracle.DataAccess时,会尝试查找它所需的非托管客户端dll。 从Oracle文档 :

Oracle.DataAccess.dll基于以下顺序搜索相关的非托管DLL(如Oracle客户端):

1.应用程序或可执行文件的目录。

2.通过应用程序配置或web.config指定的DllPath设置。

3.由machine.config指定的DllPath设置。

4. Windows注册表指定的DllPath设置。

HKEY_LOCAL_MACHINE \ SOFTWARE \ ORACLE \ ODP.NET \版本\ DllPath的

5. Windows PATH环境变量指定的目录。

所以在你的情况下,你的应用程序遵循上面的这个过程,并发现一个路径,相对于你正在使用的Oracle.DataAccess.dll程序集来说,这个路径已经过时了。

这可能只是在该机器上安装的唯一Oracle客户端太旧了。 但是,如果您在机器上安装了多个客户端,并且在不同的但较旧的安装中首先找到了非管理文件,则这起作用。 如果以后,简单的事情是在您的配置中使用dllPath配置变量,并将其指向正确的Oracle Home Bin文件夹:

 <configuration> <oracle.dataaccess.client> <add key="DllPath" value="c:\oracle\product\1.1.0-xcopy-dep\BIN"/> </oracle.dataaccess.client> </configuration> 

如果要安装新的客户端副本,则xcopy版本是最小的,并包含“即时客户端”,并将上面的DllPath指向此新位置。 但任何oracle客户端安装将工作。

但是,如果你想避免所有这些不受管理的客户端解析的东西,看看你是否可以更新你的应用程序来使用100%的托管提供者,而不是真正的一个或两个托管的程序集,而不依赖于unmananged文件。

它也有可能是你没有加载Oracle.DataAccess.dll,你认为你是如果它安装在您的bin目录和你的GAC,但我认为这是不太可能的senario。 请参阅程序集解析过程以获取更多信息。

  • 在64位机器上,将C:\ Windows \ SysWOW64中的“msvcr71.dll”复制到您的应用程序的bin目录中。
  • 在32位计算机上,将C:\ Windows \ System32中的“msvcr71.dll”复制到您的应用程序的bin目录中。

http://randomdevtips.blogspot.com/2012/06/provider-is-not-compatible-with-version.html

最近,我不得不在一个较老的项目上工作,解决方案和所有包含的项目都是针对x32平台的。 我一直试图在所有的地方复制Oracle.DataAccess.dll和所有其他建议的Oracle文件,但是每次都碰壁。 最后,灯泡点亮(8小时后:)),并要求检查已安装的ODAC组件及其平台。 我已经安装了所有的64位(x64)ODAC客户端,但不是32位(x32)。 安装了32位ODAC,问题消失了。

如何检查已安装的ODAC的版本:查看文件夹C:\ Windows \ assembly。 “处理器架构”属性将通知安装ODAC的平台。

灯泡点亮八小时是很长的时间。 难怪我总是不得不在工作:)。

克里斯的解决方案也为我工作。 然而,我得到了一个跟随错误信息,指出:

 Could not load file or assembly 'Oracle.DataAccess' or one of its dependencies. An attempt was made to load a program with an incorrect format. 

显然,在Oraclish的外语中,这意味着你的程序要么是针对所有的平台,要么是32位的机器。 只需将项目属性中的目标平台更改为64位,并希望获得最佳效果。

我有与Oracle.DataAccess.dll v4.121.2.0相同的问题。 与2-家庭安装(32和64位版本)。 32位版本的workerd,64位版本没有。

在我的情况下(经过两天的尝试),我发现问题是在64位家庭版本的权限。 该版本中的许多目录具有唯一的重写权限,其中“Authenticated Users”角色没有“读取”访问权限,默认情况下在父目录中设置该权限。 这些子目录包括“bin”,“network / admin”,“nls”,“oracore”,“RDBMS”等等。 我发现他们通过从sysinternals筛选出“访问被拒绝”结果在“进程监视器”(Procmon.exe)实用程序。 一旦权限从父目录继承到那些子子目录,一切都开始工作。

我没有什么重写整个Oracle主目录的权限,所以我一次只做了一个目录,但是我猜如果你不担心安全问题,可以在整个相应的oracle主目录下重新设置它。

在安装了适用于Visual Studio 2015的Oracle Data Tools之后,我遇到了这个问题,然后和甲骨文打了一个小时。 我决定尝试再次重新安装Oracle客户端,而不是像文件复制,配置更改等这样的混乱,这对我很有帮助。

这里有很多理论上的答案,但是这里有一个可以复制,粘贴和测试的代码示例:

  1. 我安装了Oracle Express数据库OracleXE112 ,它已经附带了一些预安装的演示表。
  2. 当您启动安装程序时,系统会要求您输入密码 。 我输入“xxx”作为密码。 (不用于生产)
  3. 我的服务器在机器192.168.1.158上运行
  4. 在服务器上,您必须明确允许访问Windows 防火墙中的进程TNSLSNR.exe。 这个进程监听端口1521.如果你从下面的代码中得到一个超时错误,请检查你的防火墙。
  5. 选项A:对于C#(.NET2或.NET4),您可以下载ODAC11 ,您必须将Oracle.DataAccess.dll添加到您的项目中。 此外,这个DLL依赖于:OraOps11w.dll,oci.dll,oraociei11.dll(130MB!),msvcr80.dll。 这些DLL必须与EXE位于同一目录中,或者必须在以下位置指定DLL路径: HKEY_LOCAL_MACHINE\SOFTWARE\Oracle\ODP.NET\4.112.4.0\DllPath 。 在64位机器上另外写入HKLM\SOFTWARE\Wow6432Node\Oracle\...
  6. 选项B:如果你已经下载了ODAC12,你需要Oracle.DataAccess.dll,OraOps12w.dll,oci.dll,oraociei12.dll(160MB!),oraons.dll,msvcr100.dll。 注册表路径是HKEY_LOCAL_MACHINE\SOFTWARE\Oracle\ODP.NET\4.121.2.0\DllPath
  7. 选项C:如果你不想要超过100 MB的巨大的DLL,你应该下载ODP.NET_Managed12.xxxxxxxx.zip,其中你会发现Oracle.ManagedDataAccess.dll ,它只有4 MB,是一个纯粹的托管的DLL在32位和64位进程以及取决于没有其他的DLL,并不需要任何注册表项。
  8. 下面的C#代码适用于我, 没有在服务器端进行任何配置 (只是默认的安装):
using Oracle.DataAccess.Client;
要么
using Oracle.ManagedDataAccess.Client;

 ....

string oradb = "Data Source=(DESCRIPTION="
    + "(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.1.158)(PORT=1521)))"
    + "(CONNECT_DATA=(SERVER=DEDICATED)));"
    + "User Id=SYSTEM;Password=xxx;";

using (OracleConnection conn = new OracleConnection(oradb)) 
 {
    conn.Open();
    using (OracleCommand cmd = new OracleCommand())
     {
        cmd.Connection = conn;
        cmd.CommandText = "select TABLESPACE_NAME from DBA_DATA_FILES";

        using (OracleDataReader dr = cmd.ExecuteReader())
         {
            while (dr.Read())
             {
                listBox.Items.Add(dr["TABLESPACE_NAME"]);
             }
         }
     }
 }