为啥 Oracle.ManagedDataAccess 不工作而 Oracle.DataAccess 工作?
Posted
技术标签:
【中文标题】为啥 Oracle.ManagedDataAccess 不工作而 Oracle.DataAccess 工作?【英文标题】:Why would Oracle.ManagedDataAccess not work when Oracle.DataAccess does?为什么 Oracle.ManagedDataAccess 不工作而 Oracle.DataAccess 工作? 【发布时间】:2013-07-01 14:48:50 【问题描述】:我正在开发一个非常简单的应用程序,我打算用它来解决我在几台机器上遇到的问题,但在我还没走到那一步之前,我遇到了一些问题,包括 cpu 架构差异和 Oracle 数据库库。
我有一个列在tnsnames.ora
中的数据库服务器,它位于我的C:\oracle\11g\network\admin
目录中。如果我 tnsping 此服务器,我会得到所需的响应。如果我使用 Oracle.DataAccess.Client 编写我的 C# 程序以使用以下代码连接到该服务器,它就可以工作。
string connectionString = "Data Source=DSDSDS;User Id=UNUNUN;Password=PWPWPW;";
DataTable dataTable = new DataTable();
using (var connection = new OracleConnection(connectionString))
connection.Open();
using (var command = new OracleCommand())
command.Connection = connection;
command.CommandText = sql;
command.CommandType = CommandType.Text;
using (var oda = new OracleDataAdapter(command))
oda.Fill(dataTable);
但是,Oracle.DataAccess 取决于运行它的系统的体系结构。我看到还有另一个库 Oracle.ManagedDataAccess 是架构独立的。当我使用这个库时,它不再能够连接到服务器。一个ORA-12545: Network Transport: Unable to resolve connect hostname
被抛出。
为什么会这样?这两个库之间有什么不同,因为根据我目前所读到的内容,这应该不是问题。
额外信息:
%ORACLE_HOME% 和 %TNS_ADMIN% 未定义(请记住 tnsping 和 Oracle.DataAccess 有效) PATH 定义了C:\oracle\11g\BIN
。
我的机器只有一个tnsnames.ora
文件
如果我将 tnsnames.ora 移动到与我的 .exe 文件相同的位置,它就可以工作。为什么Oracle.DataAccess 可以在C:\oracle\11g\network\admin
目录下找到tnsnames.ora 而Oracle.ManagedAccess 却找不到?
【问题讨论】:
我实际上遇到了同样的问题,不管 app.config 中的 TNS_ADMIN 设置如何。 你解决了吗?你能解释一下吗? 【参考方案1】:在 ODP.NET、Managed Driver 中解析 TNS 名称的优先顺序是这样的(参见here):
-
.NET 配置文件中“dataSources”部分中的数据源别名。
tnsnames.ora 文件中的数据源别名,位于 .NET 配置文件中“TNS_ADMIN”指定的位置。
tnsnames.ora 文件中的数据源别名与 .exe 位于同一目录中。
tnsnames.ora 文件中的数据源别名存在于 %TNS_ADMIN%(其中 %TNS_ADMIN% 是环境变量设置)。
%ORACLE_HOME%\network\admin 中的 tnsnames.ora 文件中的数据源别名(其中 %ORACLE_HOME% 是环境变量设置)。
我相信您的示例适用于 Oracle.DataAccess 但不适用于 Oracle.ManagedDataAccess 的原因是后者不支持基于 Windows 注册表的配置(请参阅documentation) - ODP.NET 安装设置了 ORACLE_HOME 注册表项( HLKM\SOFTWARE\Oracle\Key_NAME\ORACLE_HOME),只有非托管部分才能识别。
【讨论】:
好吧,这确实让空气稍微好一些。但是我的最新问题是“无法识别的配置部分 oracle.manageddataaccess.client”。看起来也需要“尝试将 tnsnames.ora 的路径添加到配置文件中:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<oracle.manageddataaccess.client>
<version number="4.112.3.60">
<settings>
<setting name="TNS_ADMIN" value="C:\oracle\product\10.2.0\client_1\NETWORK\ADMIN\" />
</settings>
</version>
</oracle.manageddataaccess.client>
</configuration>
【讨论】:
如果 TNS_ADMIN 的值正确,那么问题可能出在版本号上。尝试使用为了避免不知道在哪里寻找 TNSNAMES.ORA 的所有 Oracle 混乱(我有多个 Oracle 版本和 32/64 位的额外混淆),您可以将现有 TNSNAMES.ORA 中的设置复制到您自己的配置文件并将其用于您的连接。 假设您对 TNSNAMES.ORA 中的“DSDSDS”引用感到满意,它映射到以下内容:
DSDSDS=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(Host=DSDSDSHost)(Port=4521)))(CONNECT_DATA=(SERVICE_NAME=DSDSDSService)))您可以在第一个“=”之后获取文本,并在使用“DSDSDS”的任何地方使用它,并且无需查找 TNSNAMES.ORA 即可知道如何连接。 现在您的连接字符串将如下所示:
string connectionString = "Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(Host=DSDSDSHost)(Port=4521)))(CONNECT_DATA=(SERVICE_NAME=DSDSDSService)));User Id=UNUNUN;Password=PWPWPW;";
【讨论】:
我应该将 Connection Timeout 参数放在那个长长的 munster 中的什么位置? 所有允许的属性都用分号分隔。数据源属性使它看起来像堂兄它! Oracle 文档有完整的属性列表(包括连接超时,您可以在双引号内的最后一个分号后添加):docs.oracle.com/cd/B13789_01/win.101/b10117/features001.htm .Net 5 应用程序最简单的工作解决方案!【参考方案4】:一旦我在连接字符串中找到了它要查找的格式,它就可以像 Oracle.ManagedDataAccess 一样正常工作。无需单独处理任何事情。
DATA SOURCE=DSDSDS:1521/ORCL;
【讨论】:
【参考方案5】:我遇到了类似的问题......为了解决这个问题,我所做的是卸载 ODP。 NET 并重新安装在与 oracle 服务器相同的目录中......使用服务器选项您会注意到大多数产品已经安装(在安装 12c 数据库时)因此只需选择其他功能并最终完成安装。 ...
请注意,只有当您在同一台机器(即您的笔记本电脑)上安装了 12c 时,此解决方法才有效............
如果您的数据库位于笔记本电脑以外的服务器计算机上,请选择客户端选项而不是服务器,然后在您的 app.config 中包含 TNS_ADMIN 并且不要忘记指定版本...
因为我的安装是在我的笔记本电脑上,所以我的 App.config 如下:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>
/////////the below code is a sample from oracle company////////////////
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.Common;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Oracle.ManagedDataAccess.Client;
///copy these lines in a button click event
string constr = "User Id=system; Password=manager; Data Source=orcl;";
// Click here and then press F9 to insert a breakpoint
DbProviderFactory factory =
DbProviderFactories.GetFactory("Oracle.ManagedDataAccess.Client");
using (DbConnection conn = factory.CreateConnection())
conn.ConnectionString = constr;
try
conn.Open();
OracleCommand cmd = (OracleCommand)factory.CreateCommand();
cmd.Connection = (OracleConnection)conn;
//to gain access to ROWIDs of the table
//cmd.AddRowid = true;
cmd.CommandText = "select * from all_users";
OracleDataReader reader = cmd.ExecuteReader();
int visFC = reader.VisibleFieldCount; //Results in 2
int hidFC = reader.HiddenFieldCount; // Results in 1
MessageBox.Show(" Visible field count: " + visFC);
MessageBox.Show(" Hidden field count: " + hidFC);
reader.Dispose();
cmd.Dispose();
catch (Exception ex)
MessageBox.Show(ex.Message);
MessageBox.Show(ex.StackTrace);
【讨论】:
我希望配置具有您在答案中引用的节点?【参考方案6】:就我而言,上面所说的一切都很好,但我仍然收到ORA-12545: Network Transport: Unable to resolve connect hostname
我尝试 ping Oracle 机器并发现我看不到它并将其添加到主机文件中。然后我收到另一条错误消息ORA-12541: TNS:no listener
。经过调查,我意识到从不同的机器上 ping 相同的主机名得到不同的 IP 地址(我不知道为什么),我更改了主机文件中的 IP 地址,100% 解决了问题。
我很费心写我的经验,因为它看起来很明显,但是虽然我确定问题出在上述设置中,但我完全忘记检查我是否真的可以看到远程数据库机器。当你不知道发生了什么事情时,请记住......
这些链接对我帮助很大:
http://www.moreajays.com/2013/03/ora-12545-connect-failed-because-target.html http://www.orafaq.com/wiki/ORA-12541
【讨论】:
【参考方案7】:晚会“有点”迟到,但真正的答案是 - 如果您使用 Oracle.ManagedDataAccess
ODP.NET 提供程序,您应该忘记 network\admin
、Oracle client
、Oracle_Home
等内容。
这是你需要的
-
下载并安装 Oracle Developer Tools for VS 或 ODAC。注意 - 开发工具将为您安装 ODAC。这将在
C:\Program Files (x86)
下创建相对较小的安装。拥有完整的开发工具,小于 60Mb
在您的项目中,您将安装带有相应版本的 ODP.net (Oracle.ManagedDataAccess.dll) 的 Nuget 包,您将参考这些包
此时您有 2 个连接选项。
a) 在连接字符串中设置datasource
,格式如下
DataSource=ServerName:Port/SID . . .
或 DataSource=IP:Port/SID . . .
b) 创建tnsnames.ora
文件(只是它与以前的经验不同)。有条目:
AAA = (描述 = (地址 = (协议 = TCP)(主机 = 服务器名或 IP)(端口 = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = SIDNAME)))
然后将此文件放入运行应用程序的 bin 文件夹中。
现在您可以使用您的连接名称进行连接 - DataSource=AAA . . .
因此,即使您有 tnsnames.ora,但使用 ODP.net managed 它的工作方式有点不同 - 您创建本地TNS 文件。现在,很容易管理它。
总而言之 - 使用 托管,无需繁重的 Oracle 客户端、Oracle_home
或了解 Oracle 安装文件夹的深度。一切都可以在您的 .net 应用程序结构中完成。
【讨论】:
【参考方案8】:我收到了同样的错误信息。为了解决这个问题,我只是用旧的Oracle.DataAccess
程序集替换了Oracle.ManagedDataAccess
程序集。如果您需要在新装配中找到新功能,此解决方案可能不起作用。就我而言,我有更多优先级更高的问题,然后尝试配置新的 Oracle
程序集。
【讨论】:
以上是关于为啥 Oracle.ManagedDataAccess 不工作而 Oracle.DataAccess 工作?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 DataGridView 上的 DoubleBuffered 属性默认为 false,为啥它受到保护?