我正在尝试在我的ASP.net项目中使用 Oracle ODP.NET 11g(11.1.0.6.20)Instant Client 作为数据提供商但是当我运行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
答案 0 :(得分:87)
我一直在研究这个问题,你只需要从同一个下载版本的ODP.Net中获取所有相应的DLL,并将它们放在与Exe文件相同的文件夹中,因为ODP.Net很挑剔关于不混合版本号。
我在这里解释了如何执行此操作:http://splinter.com.au/using-the-new-odpnet-to-access-oracle-from-c 这是它的要点:
答案 1 :(得分:45)
你应该在这里“忽略”所有x86 / x64的谈话,而不是尝试使用ODP.NET托管驱动程序(如果你使用的是.Net v4 +):
https://www.nuget.org/packages/Oracle.ManagedDataAccess/
https://www.nuget.org/packages/Oracle.ManagedDataAccess.EntityFramework/
Oracle ODP.net Managed vs Unmanaged Driver
避免所有“非托管”DLL什么架构问题! :D(约时间Oracle)。
NuGet包(也适用于11g):
旧/手动方法:
有关如何转换为使用托管库的信息:
答案 2 :(得分:34)
我只安装了适用于.NET 2.0的Oracle数据提供程序(11.1.0.6.20),而我没有安装 Oracle Instant Client(11.1.0.6.0)。
我刚安装它,错误就消失了!
答案 3 :(得分:32)
这可能是由针对32位Oracle客户端运行64位.NET运行时引起的。如果您的服务器在64位上运行应用程序,则会发生这种情况。它将运行64位运行时的.NET应用程序。您可以在VS中的项目上设置CPU标志,以便在32位运行时中运行。
答案 4 :(得分:19)
让我们做一些总结:
错误消息"提供商与Oracle客户端版本不兼容" 可能由多种原因引起。
您没有安装Oracle客户端。在这种情况下,错误消息确实具有误导性。
Oracle Data Provider for .NET(ODP.NET,即文件Oracle.DataAccess.dll
)未包含在Oracle Instant Client中,必须单独安装(从32-bit Oracle Data Access Components (ODAC) 或64-bit Oracle Data Access Components (ODAC) Downloads下载)或者您必须在Oracle Universal Installer(OUI)中选择相应的选项。
注意,在安装Oracle Data Provider> = 12.1时,提供程序不会自动注册到GAC中。如果需要,您必须手动注册,请参阅Oracle Doc 2272241.1。
ODP.NET的版本与安装的Oracle客户端版本不匹配。你必须检查次要版本号!例如,Oracle.DataAccess.dll
版本 4.112.3.0 与Oracle客户端 11.2.0.4 不兼容。仔细检查ODP.NET和Oracle Client的版本。您可以使用oraociei*.dll
和/或OraOps*w.dll
上的sigcheck来获取Oracle客户端版本。
请注意不同的编号方案。文件版本 4.112.3.0 表示: .NET Framework版本4,Oracle版本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托管驱动程序)
.NET Framework版本不匹配。例如,如果使用Target .NET Framework 2.0编译应用程序,则无法使用ODP.NET版本4.x. .NET Framework目标版本必须等于或高于ODP.NET版本。
开发计算机上的Oracle.DataAccess.dll
版本(即编译时加载的版本)高于目标计算机上的版本。
请注意Oracle.DataAccess.dll
可能会从GAC加载,默认情况下优先于任何本地提供的文件。
<强>解决方案强>
考虑使用ODP.NET托管驱动程序,可以从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>
不需要Version=...
或processorArchitecture=...
等属性。 您的应用程序将加载正确的 - &gt;未经100%验证Oracle.DataAccess.dll
,具体取决于所选的体系结构和目标.NET框架(前提是它已正确安装)
如果您不知道目标计算机上的Oracle客户端版本(例如,它可能是您客户的计算机):转到上面提到的下载页面并下载最少的 XCopy Oracle数据访问组件的版本。解压缩zip并将Oracle.DataAccess.dll
文件复制到本地计算机。在你的VS项目中引用这个(很可能是过时的)DLL。此DLL的版本是您的应用程序将使用的最低版本的ODP.NET。运行应用程序时,GAC中的发布者策略将重定向到实际安装的版本。
我不认为将单个DLL复制到某些文件夹是一种聪明的方法。它可能适用于裸体&#34;但如果您的目标计算机安装了任何Oracle产品,那么版本不匹配的风险很高。从您的计算机上卸载所有Oracle产品并进行全新安装。看看How to uninstall / completely remove Oracle 11g (client)?它是为了得到一台非常干净的机器。
如果您必须同时使用32位和64位应用程序,请按照此说明在一台计算机上安装两个版本:
假设:Oracle Home称为OraClient11g_home1
,客户端版本为11gR2。
(可选)删除所有已安装的Oracle客户端
下载并安装Oracle x86客户端,例如下载到C:\Oracle\11.2\Client_x86
将Oracle x64客户端下载并安装到不同的文件夹中,例如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_x86
和C:\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
)可能是明智的选择。
答案 5 :(得分:5)
在目标机器上安装ODP.Net,它应该解决问题...复制dll看起来不是一个好主意......
答案 6 :(得分:5)
对于Oracle 11g(11.1.0.7.20),我必须添加以下dll和我的Exe才能工作。
答案 7 :(得分:4)
经过几个小时的故障排除后,我发现这个问题是由于我的项目bin目录中有Oracle.DataAccess.dll(v4.0)引起的,但运行时也加载了Oracle.DataAccess.dll(v2.x) GAC。删除和读取项目引用中的Oracle.DataAccess条目为我解决了这个问题。
在我的情况下,这里提到的其他文件似乎没有必要。
“提供程序与Oracle客户端版本不兼容”的根本原因是(通常)托管程序集正在尝试加载与版本不匹配的非托管库。您似乎可以通过在web.config中指定库路径来强制Oracle驱动程序使用正确的库1
<configuration>
<oracle.dataaccess.client>
<settings>
<add name="DllPath" value="C:\oracle\bin"/>
<!-- ... -->
</settings>
</oracle.dataaccess.client>
</configuration>
答案 8 :(得分:4)
在浪费了三个小时之后我的问题就是:
缺少OraOps11w.dll
为什么要生成“提供程序与Oracle客户端版本不兼容”错误消息?它必须是Oracle糟糕的编码/测试。我从1994年开始使用Oracle,自2002年以来多次使用.Net。它几乎总是很痛苦。
每个人都应该卸载Oracle并遵循上面的Chris解决方案(最佳答案)。这应该每次都有用
在StackOverflow上的另一篇文章中,这是如何卸载Oracle(忘记Oracle卸载工具,因为它无法正常工作):
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
答案 9 :(得分:2)
对于仍有此问题的人:基于这篇文章
http://oradim.blogspot.com/2009/09/odpnet-provider-is-not-compatible-with.html
我发现我的服务器缺少Microsoft C ++ Visual Runtime Library - 因为安装了Visual Studio,我在dev机器上安装了它。我从这里下载并安装了(当前)最新版本的库:
http://www.microsoft.com/en-us/download/details.aspx?id=13523
离开设置并从C#进行oracle调用make it!
答案 10 :(得分:2)
以下是我为解决这个持续3个小时的问题所做的工作:
在位于C:\oracle\product\11.2.0
的Oracle主目录下,我有一个名为client_1
的文件夹,我之前为Windows 64位安装了ODP.NET
位。
稍后在尝试使用Visual Studio 2012调试我的ASP.NET Web API应用程序时,我不断收到此错误消息: 提供程序与Oracle客户端版本不兼容 强>
搜索Google我发现这种情况正在发生,因为我使用的是ODP.NET
64位。然后我为Windows 32位抓取ODP.NET
并安装它但我仍然收到相同的错误消息。
解决方案:删除了文件夹client_1
和resinstalled ODP.NET
32位。安装程序有点混合了64位版本和32位版本的位。去图......
现在我又开心了,我可以开一个新的OracleConnection
。最后! :)
答案 11 :(得分:2)
TLDR版本:
完整版:
首先,让我们确保了解旧的未经授权的提供程序(而不是新的12c 100%托管提供程序)的组件。它由两部分组成:
简单来说,Oracle.DataAccess.dll几乎只是一个包装器,将.net指令转换为非托管客户端的ORACLE-NET指令。
也就是说,当您加载Oracle.DataAccess时,它会尝试查找所需的非托管客户端dll。来自Oracle Documentation:
Oracle.DataAccess.dll搜索依赖的非托管DLL(例如 作为Oracle客户端)基于以下顺序:
1.应用程序或可执行文件的目录。
2.应用程序配置或web.config指定的.DllPath设置。
3.由machine.config指定的DllPath设置。
4. Windows注册表指定的4.DllPath设置。
HKEY_LOCAL_MACHINE \ SOFTWARE \ ORACLE \ \版本ODP.NET \ DllPath的
5. Windows PATH环境变量指定的目录。
因此,在您的情况下,您的应用程序遵循上述过程并找到了一条路径,该路径具有与您正在使用的Oracle.DataAccess.dll程序集相比过大的无法使用的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 version是最小的并包含“即时客户端”,并将DllPath指向上方的新位置。但任何oracle客户端安装都可以。
但是如果你想避免所有这些非托管客户端解析的东西,看看你是否可以更新你的应用程序以使用100%托管提供程序 - 它实际上只是一个或两个托管程序集,而不依赖于无人管理文件。 / p>
如果它安装在你的bin目录和你的GAC中,你也可能没有加载你认为你的Oracle.DataAccess.dll,但我认为这是不太可能的senario。有关详细信息,请参阅assembly resolution process。
答案 12 :(得分:2)
同时查找IIS应用程序池启用32位真或假标志,当您看到此消息时,某些oracle论坛指示我这个!
答案 13 :(得分:2)
我遇到了完全相同的问题。我在编译应用程序后删除了(并忘了我已删除)oraociei11.dll。并且它在尝试执行时发出此错误。所以当它无法找到oraociei11.dll的dll时,它会显示此错误。可能还有其他情况会出现此错误,但这似乎是其中之一。
答案 14 :(得分:2)
在我看来,虽然你有ODP与Oracle Istant客户端,但ODP可能会尝试使用实际的Oracle客户端。您是否在计算机上安装了标准Oracle客户端?我记得Oracle在同一台机器上遇到多个客户端时非常挑剔。
答案 15 :(得分:1)
我遇到了类似的问题,根本原因是GAC具有2个oracle.dataaccess版本,即v4.0_4.112.2.0和v4.0_4.112.4.0。我的应用程序指的是v4.0_4.112.2.0,所以当我从GAC删除v4.0_4.112.4.0时,它工作正常。
GAC路径:C:\ Windows \ Microsoft.NET \ assembly \ GAC_64 \ Oracle.DataAccess
要删除版本,只需从GAC删除相应的文件夹即可。
答案 16 :(得分:1)
我在安装适用于Visual Studio 2015的Oracle数据工具之后遇到了这个问题,然后与Oracle争夺了一个小时。我决定再次尝试重新安装Oracle客户端而不是文件复制,配置更改等等,这对我有用。
答案 17 :(得分:1)
我没有走上获取新DLL的道路。我们有一堆现有项目完美无缺,只有我的新项目给我带来了麻烦所以我决定尝试其他的东西。
我的项目使用的内部开发的Internal.dll依赖于Oracle.DataAccess.dll v4.112.3.0
。出于某种原因,在发布时,Visual Studio始终上传v4.121.0.0
,即使它未在任何配置文件中明确指定。这就是我收到错误的原因。
所以我做的是:
/bin
(为了安全起见)。/bin
。myWebSite.csproj
中,但显示错误的版本:v4.121.0.0
而不是v4.112.3.0
。我手动更改了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>
答案 18 :(得分:1)
IIS / IWAM用户是否拥有Oracle目录的权限?您是否可以使用其他应用程序(例如Excel或Access?
)连接到此数据源答案 19 :(得分:1)
如果您有多个oracle客户端,或者使用不同版本的oracle客户端,则在使用非托管oracle引用时可能会发生此问题。 有两种解决方法:
第一个快速的解决方案是删除非托管引用,并使用NuGet中的托管引用,然后再使用此选项Differences between the ODP.NET Managed Driver and Unmanaged Driver
第二个解决方案是修复项目非托管目标版本,如下所示:
然后检查oracle GAC版本
如果您注意到版本不同,则这是一个问题,要解决此问题,我们需要重定向程序集版本(在启动项目中,转到配置文件并添加以下部分)
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Oracle.DataAccess" publicKeyToken="89b483f429c47342" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="4.121.2.0" />
</dependentAssembly>
</assemblyBinding>
答案 20 :(得分:1)
解决此问题只需两步。
答案 21 :(得分:1)
我有同样的问题,但在我的情况下,我不能只将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>
答案 22 :(得分:1)
我们遇到了同样的问题,因为我们的DBA更新了网络共享上的Oracle.Data.dll程序集。从项目中删除引用并再次添加它可以解决问题。
答案 23 :(得分:0)
克里斯的解决方案也适用于我。但是,我收到了一条跟踪错误消息:
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位计算机。 只需将Project Properties中的目标平台更改为64位,并希望获得最佳效果。
答案 24 :(得分:0)
最近,我不得不处理一个较旧的项目,其中解决方案和所有包含的项目都针对x32平台。我一直试图在所有地方复制Oracle.DataAccess.dll和所有其他建议的Oracle文件,但每次都碰壁。最后,头部的灯泡点亮(8小时后:)),并要求检查已安装的ODAC组件及其平台。我已经安装了所有64位(x64)ODAC客户端,但没有安装32位(x32)。安装了32位ODAC,问题就消失了。
如何检查已安装的ODAC的版本:查看文件夹C:\ Windows \ assembly。 “处理器体系结构”属性将通知平台已安装的ODAC。
灯泡点亮需要8个小时。难怪我总是不得不工作:)。
答案 25 :(得分:0)
我在Oracle.DataAccess.dll v4.121.2.0中遇到了同样的问题。与2-家庭安装(32和64位版本)。 32位版本的worker,64位版本没有。
在我的情况下(经过2天的尝试)我发现问题是64位家庭版本的权限。该版本中的许多目录专门覆盖了权限,其中&#34;经过身份验证的用户&#34;角色没有&#34;阅读&#34; access,在父目录上默认设置。这些子目录包括&#34; bin&#34;,&#34; network / admin&#34;,&#34; nls&#34;,&#34; oracore&#34;,&#34; RDBMS&#34 ;可能还有其他人。我通过过滤掉了#34; ACCESS DENIED&#34;导致&#34;过程监控&#34;来自sysinternals的(Procmon.exe)实用程序。一旦权限从父目录继承到那些子子目录,一切都开始起作用。
我没有覆盖整个oracle家庭的权限,所以我一次只做了一个目录,但我想如果你不担心安全性那么多,你可以重置它整个相应的oracle主目录。
答案 26 :(得分:-1)
http://randomdevtips.blogspot.com/2012/06/provider-is-not-compatible-with-version.html
答案 27 :(得分:-3)
这里有很多理论上的答案,但这里有一个代码的工作示例,您可以立即复制,粘贴和测试:
@RequestMapping( value = "/sendmessage" , method=RequestMethod.POST , produces="application/json")
@ResponseBody
public Map<String, Object> getData(@RequestBody Map<String, Object> data){
String text=(String) data.get("text");
String name=(String) data.get("name");
System.out.println(text+","+name);
Map<String, Object>rval = new HashMap<String, Object>();
rval.put("success",true);
return rval;
}
中指定DLL路径。在64位计算机上,另外写入HKEY_LOCAL_MACHINE\SOFTWARE\Oracle\ODP.NET\4.112.4.0\DllPath
HKLM\SOFTWARE\Wow6432Node\Oracle\...
using Oracle.DataAccess.Client; or 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"]); } } } }