我该如何在.NET中使用Oracle?

26

很遗憾,我想从 .NET 使用 Oracle,但感觉就像回到了1997年。恰当的解释似乎是软弱的表现,注册表和环境变量似乎非常重要。

这是我目前为止的进展:

我在 Oracle.com 上填写了一个关于我的生活的大型表格,并下载了 ODBC Windows 64-bit Instance Client, 11.2.0.3.0 并将其解压到文件夹中。 Basic Windows 64-bit Instant Client, 11.2.0.3.0 压缩并解压到与上面相同的文件夹中。

我运行了安装 .exe 文件(没有 MSI,记住这是1997年)。

我添加了一个指向公司 TNSNames.ora 文件的 TNS_NAMES 环境变量,在网络共享上设置了快速 DSN,并运行了测试 - 成功了!

然后,我下载了最新的针对 .NET 4.0 的 ODP.NET XCOPY 版本,并将其复制到源代码控制工作区下的 Dependencies 文件夹中。

我将我的项目引用添加到 Dependencies\odp.net4\odp.net\bin\4\Oracle.DataAccess.dll

我读到需要让托管的 ODP.NET 知道它可以在哪里找到其未管理的 Oracle 库,我猜测是 Dependencies\odp.net4\bin\OraOps11w.dll,但也可能是其他地方的一些 Oracle 二进制文件?

现在我正在设置一个名为 DllPath 的配置文件参数。不幸的是,Oracle 文档似乎没有意识到 .NET 配置文件需要在 configSections 部分中连接它们的部分。

这是配置文件部分:

<oracle.dataaccess.client>
  <add key="DllPath" value="D:\Trunk\Dependencies\odp.net4\bin" />
</oracle.dataaccess.client>

configSection应该填什么?我在论坛上找到的帖子只是给出一个例子,然后说“我不知道type应该是什么类型”,这才是关键!

有人可以给我建议吗?有人知道从.NET查询Oracle视图的白痴指南链接吗?

我能否在1997年做些事情,以免在2012年使用Oracle?

更新

快速更新一下。我将OraOps11w.dll复制到输出bin文件夹中,并删除了之前添加的任何web.config文件更改。

现在我遇到以下错误,正在研究:

  

无法加载文件或程序集“Oracle.DataAccess”或其一项依赖项。尝试加载格式不正确的程序。

其他一些论坛讨论在GAC中注册Oracle.DataAccess.dll,但我很想避免这样做-我也看不出有什么区别,但我会尝试一下。

更新2

在GAC中注册Oracle.DataAccess.dll库没有任何影响,我已注销它。

工作周的结束就要来临了,我必须赶火车,但我已向这里的另一个开发团队发送了电子邮件,并希望他们以前曾经应对过这个问题(而不是像其他人一样使用每夜的提取)。

更新3

今天早上我下载并设置了带有64位版本的IIS Express 8.0 RC。64位版本不受VS2010支持,因此需要从命令行运行。这很简单,通过查看任务管理器,我能够看到VS用于iisexpress.exe *32的命令行。

不幸的是,当浏览由64位IIS Express托管的我的网站时,我遇到了这个错误:

  

处理程序“ExtensionlessUrl-Integrated-4.0”在其模块列表中具有错误模块“ManagedPipelineHandler”

这也是该线索的一个问题,所以我将尝试使用32位版本的ODP.NET。

更新4

我下载了完整的32位版本安装程序,但是当我看到Oracle通用安装程序时,我感到恐慌。它看起来太90年代了,无法信任我的宝贵开发框。因此,我正在使用32位“XCopy”客户端,这使我能够启动我的网站首页,因此参考文献正在工作。感谢那些建议体系结构不匹配32/64问题的人。

现在我正在研究实例化新的OracleConnection时出现的错误。

  
    

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

  

更新5我想我做到了。

我下载了32位的最新11g "Instant Client",并将其放在解决方案主干代码的\Dependencies文件夹中。我将此文件夹添加到%PATH%系统环境变量中,并将OraOps11w.dll文件放入其中。

最后,_oracleConnection = new OracleConnection(connectionString)没有抛出异常!现在我需要确保在部署到生产环境时桌子上有一瓶拉弗洛伊格威士忌。

因此,对于在Windows 7、64位操作系统上的IIS Express 7.5(它是一个32位进程):

  • 下载并提取32位11g "Instant Client"到某个文件夹,并将此位置添加到您的PATH中。 Oci.dll是主要的Oracle客户端非托管库。

  • 下载并提取32位ODP.NET到某个文件夹。

  • 将OraOps11w.dll复制到Instant Client所在的主文件夹(上面的文件夹)中。

  • 添加指向TNSNames.ora文本文件所在文件夹的TNS_ADMIN环境变量。这就像一个 hosts 文件,将 Oracle 服务名称映射到服务器主机名。

  • 关闭并重新打开Visual Studio以确保您使用新的环境变量,并在ODP.NET文件夹中添加对Oracle.DataAccess.dll托管程序集的引用。

就是这样。当你知道该怎么做时,听起来相当简单。

更新 5.1

调查下面的错误,我最初没有报告它,因为我确定它是防火墙问题。我所在的公司在每台工作站上都有两个防火墙,但我刚刚打开了一个裸套接字到 Oracle 服务器,所以不可能是防火墙问题。

ORA-12541:TNS:no listener


2
虽然您的标题很有市场价值,但不太适合搜索。请考虑更改它。 - Austin Salonen
1
等到以后再改吧。否则,当我稍后搜索并发送给我的朋友时,他曾经遇到过完全相同的问题,我将无法找到它。他的解决方案是放弃并使用其他东西。 - Wug
2
“Favorited”因为老实说让Oracle驱动程序连接到Oracle数据库非常麻烦。 - NotMe
2
@LukePuplett FYI,从11.2.0.2.5开始,Oracle Data Access Component for VS附带了一个Entity Framework提供程序。此外,您可以使用一些奇怪的语法在应用程序配置中指定连接字符串,而不是在TNS_NAMES中。它仍然很麻烦,但没有那么糟糕。另外,我刚刚在运行需要与Oracle通信的程序的计算机上安装了230 MB的驱动程序,以解决DLL问题。 - cadrell0
@Austin - 什么?!我的意图是解决自己的问题,同时留下有用的东西给其他人。我向你提问的意图是想理解我选择的标题中存在的问题是什么? - Luke Puplett
显示剩余5条评论
5个回答

5
最简单的解释是指出Oracle客户端和ODAC客户端库之间的区别。
在64位机器(Windows 7+)上,您需要安装64位Oracle客户端。这是您的机器将使用它来连接部署在本地机器上的Oracle数据库的客户端。对于托管在Web服务器或其他终端服务器上的应用程序,规则相同。
诀窍在于...作为开发人员,我们的机器必须还具备.Net IDE工具。 Oracle有一个糟糕的命名约定,但基本上有两个部分:ODT(工具)和ODAC(数据访问)。 ODP.Net数据提供程序是ODAC库的一部分。
所以...回到IDE... Visual Studio是32位的,因此我们必须在32位中安装上述工具。
在开发,调试等过程中,VS.Net使用32位客户端库和数据访问库与Oracle交互。
一旦您将此应用程序部署到计算机上,它将使用加载在计算机上的任何客户端,除非特定平台被针对。
这意味着如果您针对32并部署到64,则会出现故障...反之亦然。最好的方法是将其留在任何平台部分,并简单地记住自己在做什么:)
另一件要小心的事情是确保您的客户端和ODAC包是相同版本的...您不希望有11g R2客户端和11g R5 ODAC,因为一旦部署,就会再次出现问题。
这里的警告是,如果您希望“嵌入”Oracle客户端到您的应用程序中,在这种情况下,OraOps以及其他几个库将随应用程序一起部署-这称为Oracle的Instant Client,并且也是ODAC包的一部分并包含在他们的完整客户端包中。
好消息是...
Oracle即将(2013年第一季度)发布他们的下一个ODP.Net包...它将是一个完全托管代码库...意味着不再需要匹配单独的客户端或ODAC包,并且平台将忽略32位和64位的区别...它将像旧的微软库一样运作,只是它将由Oracle构建和维护,并具有更强大的功能集。我只希望它能更快地到来。

1
+1 是所有回答中唯一提到“ODP.Net”的答案! - JonnyRaa
坏消息是,如果您正在使用任何Oracle Auth Providers for ASP.Net(Role、Profile、Membership provider等),这些提供程序与新的Oracle.ManagedDataAccess.dll不兼容。Oracle不知何故“忘记”这些提供程序也需要访问数据库。这些提供程序中提供了数据访问,并且硬编码为查找旧的Oracle.DataAccess.dll(而不是“Managed”)。因此,这进一步复杂化了已经复杂的版本控制问题,需要解决所有这些问题。 - jimo3

3
我曾经花了好几天时间在Windows 7上尝试连接Oracle。遇到的问题是,我有一个32位ASP.NET应用程序,安装了32位Oracle ODP.NET驱动程序。我没有意识到,即使ASP.NET应用程序作为32位进程运行并需要32位ODP.NET,IIS是64位进程并导致ODP.NET访问64位注册表键。您没有提到是否正在尝试为ASP.NET设置Oracle,但我将分享我的解决方法(尽管这适用于Oracle 10.2安装)。
我从我的博客文章中逐字复制注意:这会强制Oracle 11.2.0.1仅在64位环境下使用32位。 我犯的第一个错误是在Windows 7上安装Oracle 10g客户端。这行不通。如果你安装它,之后你得进行一些清理工作。
  • 前往Oracle网站下载/安装11g 32位和64位客户端。
  • 点击此处并按照“虚拟注册表项”步骤操作。
  • 打开regedit并验证HKLM\SOFTWARE\Wow6432Node\ORACLE\inst_loc指向正确位置(可能是C:\oracle\Inventory)。
  • 将注册表项指向HKLM\SOFTWARE\Wow6432Node\ORACLE\VOBHOME2.0,指向32位Oracle文件夹。
  • 创建一个ORACLE_HOME环境变量并将其指向32位文件夹。

现在,在重启后应该已经设置好了。

如果您尝试安装Oracle 10g客户端,则需要进行一些清理工作。首先,请确保完全卸载Oracle 10g,并从PATH变量中取消引用以及删除该目录。然后,找到GAC中引用的程序集:

gacutil /l | find /i "Oracle" > c:\[some directory]\oracle.txt

找到涉及Oracle.DataAccess版本10.2的行,并从GAC中删除它们。例如(除非您安装了相同版本,否则此示例将无法工作):

gacutil /u "Oracle.DataAccess, Version=10.2.0.100, Culture=neutral, PublicKeyToken=89b483f429c47342"

当我执行此操作时,我需要删除三个程序集:
  1. Oracle.DataAccess
  2. Policy.10.1.Oracle.DataAccess
  3. Policy.9.2.Oracle.DataAccess
再次提醒,您可能需要重新启动(嘿,这是Windows)。
如果您需要进行任何清理工作,我也已经写过相关博客供参考
如果“虚拟注册表项”步骤的链接失效,这里是Gadi在该帖子中的文字:
“嗨Ben,
在设计时,使用SQL Server商业智能开发工具时,Oracle连接器以32位模式运行,因此它加载32位Oracle客户端。
很可能,您会因为连接器加载了错误的Oracle客户端(oci.dll),其中TNS服务未定义而出现错误。
要解决这个问题,您有两个选择:”
  1. 在Oracle Connection Manager Editor中指定Oracle连接字符串,而不是TNS服务名称,例如以下格式:host:port/service_name

  2. 按以下方式定义虚拟注册表项(Z_SSIS):

    • 打开regedit实用程序。
    • 找到以下键:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\ORACLE
    • 右键单击ORACLE节点,然后单击“新建”->“键”。
    • 将新键命名为Z_SSIS(确保它是最后一个条目)。
    • 右键单击Z_SSIS节点,然后单击“新建”->“字符串”。
    • 将属性命名为ORACLE_HOME
    • 双击ORACLE_HOME,并将其设置为您要使用的Oracle 32位安装主目录的位置。

问候,

Gadi ""


我查看了我的IISExpress 7.5进程,它是32位的。甚至没有想到微软会在2012年发布一个仅支持32位的应用程序。我正在下载64位的IISExpress 8 beta,并将报告结果。 - Luke Puplett

1
首先,为你对Oracle的纯爱点赞,并认识到他们是最好的公司,拥有最好的产品! ;)

是的,下载和安装过程真是太麻烦了。我经常在他们的网站上找不到正确的客户端下载链接,而且 Oracle 的通用产品安装程序简直太差劲了。


有时您需要在\bin目录中复制OraOps11w.dll。有时不需要。我从来没有弄清楚什么时候需要它,什么时候不需要,但我认为如果您引用的Oracle.DataAccess.dll与安装的Oracle客户端版本不完全相同,则需要OraOps11w.dll
你能解释一下你在配置文件中使用 DllPath 是为了做什么吗?Oracle 安装应该已经在 machine.config 中注册了 .NET Runtime 所需的所有内容。虽然我设置 ODP.NET 已经有一段时间了,但我不记得有什么需要在 app.config 中设置的东西,除了连接字符串。

谢谢Rally,我一直在使用DllPath指向OraOps11w.dll,但如果你说我可以将它放入我的.NET bin文件夹中,那我可能会这样做。 - Luke Puplett
是的,我通常在部署时只是将它复制到我的 \bin 文件夹中。奇怪的是,在某些服务器上,它从不关心它是否存在,而在其他服务器上,它会抛出一些版本不匹配的异常错误(我忘记了确切的消息)。 - CodingWithSpike

1

我不认为这是路径问题。"尝试加载具有错误格式的程序。"几乎总是意味着您在.NET中混合使用32位和64位程序集和DLL。

我注意到您安装了64位的Oracle客户端,我假设由于DSN创建工作正常,您正在使用64位版本的操作系统?您的问题可能来自以下几种相关情况:

  • 您的OraOps11w.dll副本可能是32位程序集,并且您正在64位应用程序中使用它
  • 您的OraOps11w.dll副本可能是64位程序集,并且您正在尝试从32位应用程序中使用它
  • Oracle Data Provider for .NET的非托管依赖项之一是32位的,并且无法加载到您的32位应用程序中(反之亦然)

我相信,如果您的应用程序专门针对x86,则必须安装32位Oracle客户端包,而不管底层操作系统平台如何(例如,即使您使用64位Windows的32位应用程序,仍需要32位Oracle客户端)

检查一些事情:

  • 请检查调用Oracle提供程序的程序集中的“平台目标”设置:x64将始终尝试以64位运行,x86将始终尝试以32位运行,“任何平台”将在运行时JIT编译为目标操作系统架构(在x86系统上为32位,在x64系统上为64位)
  • 通过corflags.exe运行OraOps11w.dll(详见此SO帖子),以查看它是32位、64位还是“任何CPU”

最后,您是否尝试过使用Oracle的内置.NET数据提供程序(System.Data.OracleClient命名空间?)

这是我能做的最好的了,因为我不知道您的应用程序的项目设置。


1
System.Data.OracleClient 不再得到维护。.NET 4 只有错误修复,微软不会再添加新功能,并建议使用 Oracle ODP.NET 库。 - Joseph Yaduvanshi
谢谢留言。我的建议更多是为了解决平台目标问题。如果.NET提供程序可以正常工作,那么x86 / x64不匹配的问题很可能在OraOps11w.dll中,如果他仍然遇到相同的错误,则可能存在一个未经管理的Oracle客户端库,该库与其应用程序的平台目标不匹配。 - Mike Marshall
+1 是因为架构不匹配。尽管我在将生成设置为 x86 时,仍然遇到了 ASP.NET 的巨大问题。 - Joseph Yaduvanshi
@Jim 稍微偏离原帖的话题,但对于只支持32位asp.net的问题,我们不得不专门将所有程序集更改为以x86为目标,然后按照这个步骤进行操作:http://technet.microsoft.com/en-us/library/cc737351.aspx - Mike Marshall
奇怪,我在Windows 2008和Windows 7上尝试了同样的事情,但似乎对ODP.NET没有影响。我曾经在Windows 2003上为其他应用程序(不使用Oracle)做过同样的技巧,它们都能正常工作。我认为Oracle在加载依赖项时会做一些奇怪的事情。 - Joseph Yaduvanshi

-1

我曾经遇到过同样的问题,并发现在拷贝版本的 Oracle.DataAccess.dll 11.x 软件安装中运行“unconfigure”和“configure”批处理文件可能会解决或有助于解决这个问题。

例如:configure.bat xxx.netx xxx\product\11.2.0\client_1


1
请将此内容发布为评论。这不是答案。 - Bond - Java Bond

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