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

Posted

技术标签:

【中文标题】提供者与Oracle客户端版本不兼容【英文标题】:The provider is not compatible with the version of Oracle client 【发布时间】:2010-10-14 03:30:47 【问题描述】:

我正在尝试在我的 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

【问题讨论】:

【参考方案1】:

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

【讨论】:

【参考方案2】:

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

【讨论】:

【参考方案3】:

我只安装了 Oracle Data Provider for .NET 2.0 (11.1.0.6.20),我没有安装 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 对我来说其他方式 - 我安装了客户端,但没有安装提供程序【参考方案4】:

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

【讨论】:

刚碰到这个。在(32 位)测试应用程序中工作,然后在 IIS 中失败。我没有要求所有涉及的程序集都是 32 位的,而是改为 32 位的 AppPool。【参考方案5】:

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

【讨论】:

【参考方案6】:

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

【讨论】:

您的解决方案对我有用——在我发现之前找到了您的博客文章。你是男人。谢谢! :-) 另外,使用最新版本的 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 文件夹。这可能会导致“版本不兼容”错误。【参考方案7】:

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

【讨论】:

【参考方案8】:

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

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

【讨论】:

你想说 130 MB【参考方案9】:

同时寻找 IIS 应用程序池 Enable 32-bit true or false flag,当你看到这个消息时,一些 oracle 论坛指导我这样做!

【讨论】:

【参考方案10】:

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

【讨论】:

【参考方案11】:

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

【讨论】:

【参考方案12】: 在 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

【讨论】:

【参考方案13】:

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

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

祝你好运。

【讨论】:

@mazhar-abbas,你能请。指出我可以在其中设置“启用 32 位应用程序?是在 IIS 还是 Project 中?【参考方案14】:

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

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

8 小时对于灯泡点亮来说是一段很长的时间。难怪我总是要在工作中吃力:)。

【讨论】:

注意,C:\Windows\assemblies 仅显示 .NET 框架版本 2.0 之前的程序集。 3.x/4.x版本不显示,见***.com/questions/28213105/…【参考方案15】:

为了解决这个持续了 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。最后! :)

【讨论】:

【参考方案16】:

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

在我的情况下,这里提到的其他文件似乎不是必需的。

更新

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

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

【讨论】:

谢谢!您的解决方案让我知道 2 天后工作(我有 Visual Studio 2010 Net 4,Oracle 10g 客户端)...我看到 GAC,当然我已经安装了 3 个版本的 Oracle.DataAccess.dll,我卸载了所有(和删除“DbProviderFactories”中无效的 machine.config 键),并仅重新安装 ODAC1120320 x64。它有效。【参考方案17】:

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

旧的/手动方法:

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

首先,这是 managedunmanaged 的代码对比: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 与两个 dll 一起发布(添加到 VS2010 中的应用程序文件夹

【讨论】:

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

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

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

【讨论】:

这实际上是 .NETish,而不是 Oraclish【参考方案19】:

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

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

【讨论】:

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

让我们做一些总结:

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

您没有安装 Oracle 客户端。在这种情况下,错误消息确实具有误导性。

Oracle Instant Client 中不包含用于 .NET 的 Oracle 数据提供程序(ODP.NET,即文件 Oracle.DataAccess.dll),它必须单独安装(从 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 客户端的版本。您可以在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 的引用,如下所示:

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

Version=...processorArchitecture=... 等属性不是必需的。 您的应用程序将根据所选架构和目标 .NET 框架加载正确的Oracle.DataAccess.dll(前提是它已正确安装) -> 未 100% 验证

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

我认为获取单个 DLL 并将它们复制到特定文件夹不是一种明智的方法。它可能在“裸机”机器上工作,但如果您的目标机器安装了任何 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_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 比实际答案有更多的知识要带走。因此,如果我有一个用于 .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然后问题解决了!【参考方案21】:

我没有走上获取新 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 中的引用,所以现在改为:

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

【讨论】:

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

我在使用 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 home的权限,所以我一次只做一个目录,但我想如果你不太担心安全性,你可以在整个相应的oracle home上重置它目录。

【讨论】:

【参考方案23】:

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

【讨论】:

【参考方案24】:

TLDR 版本:

请改用 12c 100% managed provider。 如果必须使用旧提供程序,则需要将 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.DllPath 设置由应用程序配置或 web.config 指定。

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

4.Windows注册表指定的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 了解更多信息。

【讨论】:

【参考方案25】:

这里有很多理论答案,但这里有一个工作示例,您可以复制粘贴并立即进行测试:

    我安装了 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# 代码适用于我在服务器端无需任何配置(只是默认安装):
使用 Oracle.DataAccess.Client; 要么 使用 Oracle.ManagedDataAccess.Client; …… 字符串 oradb = "数据源 =(DESCRIPTION=" +“(地址列表=(地址=(协议=TCP)(主机=192.168.1.158)(端口=1521)))” + "(CONNECT_DATA=(SERVER=DEDICATED)));" + "用户ID=SYSTEM;密码=xxx;"; 使用 (OracleConnection conn = new OracleConnection(oradb)) conn.Open(); 使用 (OracleCommand cmd = new OracleCommand()) cmd.Connection = 连接; cmd.CommandText = "从 DBA_DATA_FILES 中选择 TABLESPACE_NAME"; 使用 (OracleDataReader dr = cmd.ExecuteReader()) 而 (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 的源代码,但您的客户端可能存在更多您看不到的依赖项,例如由语言设置、字符集、时区等触发。当我使用Oracle.DataAccess.dll 进行跟踪时,程序总共加载了 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。【参考方案26】:

我遇到了类似的问题,根本原因是 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 中删除相应的文件夹即可。

【讨论】:

【参考方案27】:

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

    第一个快速的解决方案是删除非托管引用并使用 NuGet 中的托管引用查看此之前使用此选项Differences between the ODP.NET Managed Driver and Unmanaged Driver

    第二种解决方案是修复项目非托管目标版本,如下所示:

首先检查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>

像这样

oldVersion : 应该涵盖您的项目版本 newVersion : GAC 版本 publicKeyToken:来自 GAC

【讨论】:

以上是关于提供者与Oracle客户端版本不兼容的主要内容,如果未能解决你的问题,请参考以下文章

C# 访问Oracle数据库

windows7如何安装oracle 9i?

为啥navicat连接oracle数据库以及新建查询时会闪退

Oracle列转行函数版本不兼容解决方案

Oracle列转行函数vm_concat在19C版本不兼容解决方案

Oracle 10g,和 Oracle 11g 能互相兼容吗?还是向下兼容?