ChatGPT解决这个技术问题 Extra ChatGPT

提供者与Oracle客户端版本不兼容

我正在尝试在我的 ASP.net 项目中使用 Oracle ODP.NET 11g (11.1.0.6.20) Instant Client 作为数据提供程序,但是当我运行 aspx 页面时,我得到一个“提供程序与版本不兼容Oracle 客户端”错误消息。任何帮助,将不胜感激。

我在 Visual Studio 2005 中引用了 Data Provider,后面的代码如下所示:

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

M
Matt

我一直在进一步研究这个问题,你只需要从同一个下载版本的 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')

oci.dll(从“oci.dll.dbl”重命名)

Oracle.DataAccess.dll

oraociicus11.dll

OraOps11w.dll

orannzsbb11.dll

oraocci11.dll

ociw32.dll(从“ociw32.dll.dbl”重命名)

将所有 DLL 与 C# 可执行文件放在同一个文件夹中


你的解决方案对我有用——在我发现之前找到了你的博客文章。你是男人。谢谢! :-) 另外,使用最新版本的 ODAC,我不需要解压缩任何 JAR....dll 文件位于我的 oracle home 的各个目录中。一个简单的 Windows 搜索很快就找到了它们。
另外,我在我的开发机器上使用了最新版本的 ODAC (11.2.0.1.2),我需要的唯一文件是:oci.dll、Oracle.DataAccess.dll、oraociei11.dll、OraOps11w.dll。正如克里斯指出的那样,确保它们与您的可执行文件位于同一文件夹中。 ;-)
听起来较新的版本更容易找到 dll。伟大的!现在,oracle 将它们滚动到一个简单的 dll 中需要多长时间...
如果可以的话,这些天你可能应该使用 C# 托管驱动程序:)
如果您的客户安装了(正常)Oracle 客户端,此解决方案可能会失败,因为 Oracle.DataAccess.dll 安装在 GAC 中。在这种情况下,Oracle.DataAccess.dll 取自 GAC(优先于您的 .exe 文件夹),但其他 DLL 取自您的 .exe 文件夹。这可能会导致“版本不兼容”错误。
C
Community

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

https://i.stack.imgur.com/i7l0w.png

旧/手动方法:

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

首先,这是托管与非托管的代码比较:http://docs.oracle.com/cd/E51173_01/win.122/e17732/intro005.htm#ODPNT148

确保您已下载 ODP.NET,仅托管驱动程序 Xcopy 版本

从下载的 zip 文件中,复制并粘贴到您的项目目录中:Oracle.ManagedDataAccessDTC.dll Oracle.ManagedDataAccess.dll

Oracle.ManagedDataAccessDTC.dll

Oracle.ManagedDataAccess.dll

添加对 Oracle.ManagedDataAccess.dll 的引用

确保您的 exe 与两个 dll 一起发布(添加到 VS2010 中的应用程序文件夹)


好消息是甲骨文终于有了一个完全托管的驱动程序。拖着那个 100mb 的 dll 是一个真正的负担。
托管驱动程序对我来说非常有用 - 自从移到它之后我没有任何问题/您可以将您的项目设置回 AnyCPU 等,它非常有效:)
每个人都知道,虽然托管提供程序很好,但它缺少完整提供程序允许的许多功能。即,Oracle 的内置加密。
至少可以说,Oracle 的文档往往是“分散的”。这是一些unsupported methods的好链接。此外,驱动程序本身带有一个 readme,它概述了一些限制。
使用托管驱动程序是最终的解决方案!每次我都想当我遇到类型不匹配时花费的所有时间,我都有一个噩梦
K
Kiquenet

我只安装了 .NET 2.0 (11.1.0.6.20) 的 Oracle 数据提供程序,没有安装 Oracle Instant Client (11.1.0.6.0)。

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


您可以简单地将 4 个即时客户端 DLL 复制到与您的 EXE 相同的文件夹中,而不是安装客户端吗? (这些文件:oci.dll orannzsbb11.dll oraocci11.dll oraociicus11.dll)
@Chris:是的,你可以。不过,根据我的经验,您需要 oci.dll、orannzsbb11.dll、oraociicus11.dll、oraops11w.dll 和 oracle.dataaccess.dll
对我来说其他方式 - 我安装了客户端,但没有安装提供程序
D
Daniel

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


刚好碰到这个。在(32 位)测试应用程序中工作,然后在 IIS 中失败。我没有要求所有涉及的程序集都是 32 位的,而是改为了 32 位的 AppPool。
W
Wernfried Domscheit

让我们做一些总结:

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

您没有安装 Oracle 客户端。在这种情况下,错误消息确实具有误导性。 Oracle Instant Client 中不包含用于 .NET 的 Oracle 数据提供程序(ODP.NET,即文件 Oracle.DataAccess.dll),它必须单独安装(从 32 位 Oracle 数据访问组件 (ODAC) 或 64 位下载Oracle 数据访问组件 (ODAC) 下载),或者您必须在 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 客户端的版本。您可以在 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 相关。在 Oracle Client 11.1 之前版本“1.x”可用。 Oracle Client 11.2 引入了版本“4.x”

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 Managed Driver,它可以从 Oracle 页面下载:64-bit Oracle Data Access Components (ODAC) Downloads。在那里,您只需将 Oracle.ManagedDataAccess.dll 文件复制到您的应用程序目录,不需要其他任何东西。它适用于 32 位和 64 位。

在你的 *.csproj 中,分别。 *.vbproj 像这样编辑您对 ODP.NET 的引用: False False 属性,例如 Version=...或 processorArchitecture=... 不是必需的。您的应用程序将加载正确的 Oracle.DataAccess.dll,具体取决于所选架构和目标 .NET 框架(前提是已正确安装)-> 未经过 100% 验证

如果您不知道目标机器上的 Oracle 客户端版本(例如,它可能是您客户的机器): 转到上面提到的下载页面并下载 Oracle 数据访问组件的最低 XCopy 版本。解压缩 zip 并将 Oracle.DataAccess.dll 文件复制到本地计算机。在你的 VS 项目中引用这个(很可能是过时的)DLL。此 DLL 的版本是您的应用程序可以使用的最低版本的 ODP.NET。当您运行您的应用程序时,GAC 中的发布者策略将重定向到实际安装的版本。

我不认为采用单个 DLL 并将它们复制到某些文件夹是一种聪明的方法。它可能在“裸机”机器上工作,但如果您的目标机器安装了任何 Oracle 产品,则版本不匹配的风险很高。从您的机器上卸载所有 Oracle 产品并进行全新安装。看看如何卸载/完全删除 Oracle 11g(客户端)?它为了得到一台真正干净的机器。

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

假设:Oracle Home 名为 OraClient11g_home1,Client Version 为 11gR2。

可选择删除任何已安装的 Oracle 客户端

下载并安装 Oracle x86 客户端,例如到 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_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。


这个 IMO 比实际答案有更多的知识要带走。因此,如果我有一个用于 .net 4 的 x86 应用程序并且数据库版本在 9i 中,那么如果用户有 32 位或 64 位 Windows,他们需要什么客户端版本? Oracle 表示任何客户端版本都与任何数据库版本兼容。答案是 32 位用户安装 32 位版本,64 位用户安装 64 位版本并使用 ODP.NET 托管驱动程序来决定它正在与哪个操作系统交谈?
当您使用 ODP.NET 托管驱动程序时,不需要安装任何 Oracle 客户端 - 这是它的主要优势。它适用于 x86 和 x64 应用程序。如果没有“ODP.NET 托管驱动程序”,x86 应用程序还需要 x86(即 32 位)Oracle 客户端,无论数据库服务器架构是什么。
我刚刚遇到“需要安装 Microsoft Visual C++ 2010 Redistributable”——您应该将其添加到您的摘要中。
我认为此错误与 Oracle 或 ODP.NET 无关或引起
它对我有用,我从 nuget 包 Oracle.DataAccess.x86 安装 Oracle.DataAccess.dll,它的 Dll 版本是 2.112.1.0,所以我将安装 Oracle 客户端与版本 Oracle Database 11g Release 2 Client (11.2.0.1.0) for Microsoft Windows (x64) HERE 匹配,然后问题解决了!
p
psaxton

经过几个小时的故障排除后,我发现这个问题是由于我的项目 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。它有效。
H
HainKurt

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


S
SKG

对于 Oracle 11g (11.1.0.7.20),我必须将以下 dll 与我的 Exe 一起添加才能工作。

oci.dll OraOps11w.dll oraociicus11.dll(非常大,接近 30mb) Oracle.DataAccess.dll


你想说 130 MB
C
Community

TLDR 版本:

请改用 12c 100% 托管提供程序。

如果必须使用旧提供程序,则需要将 Oracle.DataAccess.dll 指向正确版本的非托管 Oracle 客户端 Dll。如果您的机器上安装了多个 Oracle 客户端,这可能很简单,例如在您的应用程序配置中包含“DllPath”配置变量(见下文),但您可能还需要安装一个新的 Oracle 客户端来指向。

完整版本:

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

托管 .net 组件 - Oracle.DataAccess.dll 非托管(非 .net)客户端

简单地说,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 Registry指定的DllPath设置。 HKEY_LOCAL_MACHINE\Software\Oracle\ODP.NET\version\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% 托管提供程序 - 它确实只是一两个托管程序集,而不依赖于非托管文件。

如果它安装在您的 bin 目录和 GAC 中,您也可能没有加载您认为的 Oracle.DataAccess.dll,但我认为这是不太可能的情况。有关详细信息,请参阅 assembly resolution process


P
Peter Meyer

在我看来,虽然您有带有 Oracle 即时客户端的 ODP,但 ODP 可能正在尝试使用实际的 Oracle 客户端。你的机器上是否也安装了标准的 Oracle 客户端?我记得甲骨文对同一台机器上的多个客户端非常挑剔。


佚名

我有同样的问题。编译应用程序后,我删除了(忘记了我已经删除了)oraociei11.dll。它在尝试执行时给出了这个错误。所以当它找不到 oraociei11.dll 的 dll 时,它会显示这个错误。可能还有其他情况会出现此错误,但这似乎是其中之一。


H
Hydtechie

还要寻找 IIS 应用程序池 Enable 32-bit true or false flag,当你看到这个消息时,一些 oracle 论坛给我指点了这个!


c
calderonsteven

我有同样的问题,但在我的情况下,我不能只将 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>

L
Leniel Maccaferri

这是我为解决这个持续了 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 并重新安装 ODP.NET 32 位。安装程序在某种程度上混合了 64 位版本和 32 位版本的位。想想看……现在我又开心了,我可以打开一个新的 OracleConnection。最后! :)


d
dabor

对于仍然遇到此问题的任何人:基于这篇文章

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# 的 oracle 调用成功了!


伙计……甲骨文……我们可以讨论一下吗?过来,在角落里。听着,我花了一整天的时间弄清楚“提供程序不兼容”到底是什么意思,后来才发现这是因为没有满足某些安装依赖项。请——不——我要求您让安装程序在安装时检查这些依赖项,如果不满足,请警告用户。谢谢。
顺便说一句,我不得不多次回到这个stackoverflow问题,每次都有不同的答案适用于我。这造成了多么浪费时间和金钱。
R
Robotronx

我没有走上获得新 DLL 的道路。我们有一堆现有的项目运行良好,只有我的新项目让我头疼,所以我决定尝试其他的。

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

所以我所做的是:

将 Internal.dll 从一个成功运行的项目复制到我的网站的 /bin (只是为了安全起见)。将 Oracle.DataAccess.dll 从成功运行的项目之一复制到我网站的 /bin。从我的网站添加对它们的引用。最后 Oracle.DataAccess 参考出现在 myWebSite.csproj 中,但它显示了错误的版本:v4.121.0.0 而不是 v4.112.3.0。我手动更改了 myWebSite.csproj 中的引用,因此它现在显示为: False bin\Oracle.DataAccess.dll


在 bin 文件夹中添加对 dll 的引用是一个非常糟糕的主意。
binobj 文件夹是 output 文件夹;这是构建项目时 dll 所在的位置。您应该能够随时删除这些文件夹而不会产生冲突。通常这些文件夹在源代码管理中被忽略。标准做法是创建一个 External References 文件夹,您可以在其中放置引用的 dll。
@notfed 看来你是对的。我会记住这一点。
顾名思义,它只是编译器的 hint 路径,而不是强制引用。首先在 GAC 中搜索 Oracle.DataAccess.dll。即使您完全删除 HintPath,它也应该可以工作。
O
Osama AbuSitta

如果您有多个 oracle 客户端,或者有时如果您引用不同的版本,则在使用非托管 oracle 引用时可能会发生此问题。有两种方法可以解决它:

第一个也是快速的解决方案是删除非托管引用并使用 NuGet 中的托管引用在使用此选项之前请参阅此选项 ODP.NET 托管驱动程序和非托管驱动程序之间的差异第二个解决方案是修复项目非托管目标版本,如下所示:

首先检查oracle项目参考版本(从项目参考/(依赖项>程序集)> Oracle.DataAccess右键单击>属性):

然后检查oracle GAC版本

从运行 (Win+R) "%windir%\Microsoft.NET\assembly" 到 gac

检查与您的项目平台匹配的平台

检查您的目标平台(右键单击您的项目>属性)

从 gac 文件夹搜索到 Oracle.DataAccess

右键单击 Oracle.DataAccess > 属性 > 详细信息并检查版本

如果您发现版本不同,这是一个问题,要解决它,我们需要重定向程序集版本(在启动项目中转到配置文件并添加以下部分)

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

https://i.stack.imgur.com/rHQlf.png

https://i.stack.imgur.com/FAMNu.png


D
DCookie

IIS/IWAM 用户是否对 Oracle 目录具有权限?您可以使用其他应用程序(例如 Excel 或 Access)连接到此数据源吗?


d
doekman

我们遇到了同样的问题,因为网络共享上的 Oracle.Data.dll 程序集由我们的 DBA 更新。从项目中删除引用,然后再次添加它解决了问题。


M
Mazhar Abbas

只需两步即可解决此问题。

转到应用程序池的高级设置并将“启用 32 位应用程序”标志设置为 True。确保您的 Bin 中的所有 Dll 现在都是 32 位版本...

祝你好运。


@mazhar-abbas,你能请。指出我可以在其中设置“启用 32 位应用程序?它是在 IIS 中还是在项目中?
D
David Spenard

我在安装 Oracle Data Tools for Visual Studio 2015 后遇到了这个问题,然后与 Oracle 争吵了一个小时。我决定再次尝试重新安装 Oracle 客户端,而不是像文件复制、配置更改等那样弄得一团糟,这对我有用。


p
p4ulinux

我遇到了类似的问题,根本原因是 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

https://i.stack.imgur.com/2m47P.png

https://i.stack.imgur.com/Qw4gD.png

要删除版本,只需从 GAC 中删除相应的文件夹即可。


D
DiligentKarma

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

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

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


请注意,C:\Windows\assemblies 仅显示 .NET 框架版本 2.0 之前的程序集。不显示版本 3.x/4.x,请参阅 stackoverflow.com/questions/28213105/…
C
Cameron Castillo

克里斯的解决方案也对我有用。但是,我确实收到了一条以下错误消息:

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 位,并希望获得最好的结果。


那实际上是 .NETish,而不是 Oraclish
G
Greg Z.

我对 Oracle.DataAccess.dll v4.121.2.0 有同样的问题。带 2 个家庭安装(32 位和 64 位版本)。 32 位版本工作,64 位版本没有。

就我而言(经过 2 天的尝试),我发现问题出在 64 位家庭版本的权限上。该版本中的许多目录具有专门覆盖的权限,其中“Authenticated Users”角色没有“读取”访问权限,默认情况下在父目录上设置。这些子目录包括“bin”、“network/admin”、“nls”、“oracore”、“RDBMS”和可能的其他目录。我通过从 sysinternals 过滤掉“进程监视器”(Procmon.exe)实用程序中的“访问被拒绝”结果找到了它们。一旦权限从父目录继承到这些子目录,一切就开始工作了。

我没有覆盖整个 oracle 主目录的权限,所以我一次只做一个目录,但我想如果你不太担心安全性,你可以在整个相应的 oracle 主目录上重置它。


J
JordanBean

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

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

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


E
Elmue

这里有很多理论答案,但这里有一个工作示例,其中包含可以立即复制、粘贴和测试的代码:

我安装了 Oracle Express 数据库 OracleXE112,它已经附带了一些预装的演示表。当您启动安装程序时,系统会要求您输入密码。我输入“xxx”作为密码。 (未用于生产)我的服务器在机器 192.168.1.158 上运行 在服务器上,您必须明确允许访问 Windows 防火墙中的进程 TNSLSNR.exe。此过程侦听端口 1521。如果您从以下代码中收到超时错误,请检查您的防火墙。选项 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\... 选项 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 选项 C:如果您不想要超过 100 MB 的巨大 DLL,您应该下载 ODP.NET_Managed12.xxxxxxxx.zip,您可以在其中找到 Oracle .ManagedDataAccess.dll,它只有 4 MB,是一个纯托管 DLL,它也可以在 32 位和 64 位进程中运行,并且不依赖于其他 DLL,并且不需要任何注册表项。以下 C# 代码适用于我,无需在服务器端进行任何配置(只是默认安装):

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"]);
            }
        }
    }
}

当您只需要一个正在运行的客户端时,安装整个 Oracle 数据库服务器是相当过分的。
反正你的回答很差。无需将任何 Oracle dll 复制到应用程序目录,因为默认安装时您通过 ‰PATH% 找到它们(除非您自己修改) Registy 提示仅适用于.version 4.x 并且仅适用于32 位 Oracle 客户端。但是 32 位与 64 位的不匹配是这个问题的主题。
您的评论表明您没有阅读我的答案。如果我想编写一个与 Oracle 服务器通信的应用程序,则无需从 Oracle 安装任何东西。我只是使用上面提到的 DLL 并将它与我的应用程序一起分发。所以最终用户机器上的 PATH 变量中不会有任何内容。顺便说一句,使用 PATH 变量(来自 1980 年的旧 DOS 时代)在现代软件中被高度弃用。我的回答推荐 OPTION C,它不需要任何注册表路径并且不依赖于 32 位或 64 位。我提到选项 A 和 B 只是为了完整性。
我认为如果没有正确的 %PATH% 设置,您的 Windows 将根本无法工作 - 即使在版本 10 中也是如此。我在回答中提到,使用您的应用程序手动复制任何 Oracle dll 是不明智的。我不知道这些 dll 的源代码,但您的客户端可能存在更多您看不到的依赖项,例如由语言设置、字符集、时区等触发。当我使用 {1 进行跟踪时} 那么程序总共加载了 35 个 Oracle DLL!最好正常安装 Oracle 客户端 - 当然,除非您使用 ODP.NET 托管驱动程序。
我想我提到了我的担忧:(1)安装数据库是无用的,即矫枉过正。 (2) 选项 A 和 B 仅在某些条件下有效,例如它不从注册表中读取任何 NLS 设置(您需要文件 oracle.key)。为了兼容性,您还必须考虑次要版本。例如,Oracle.DataAccess, Version=2.112.2.0 不适用于 OraOps11w.dll 版本 2.112.4.0。

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅