C# 为什么Oracle.ManagedDataAccess不工作,而Oracle.DataAccess不工作?
我正在开发一个非常简单的应用程序,我打算用它来解决我在一些机器上遇到的一个问题,但在我达到这个程度之前,我遇到了一些问题,包括cpu体系结构的差异和Oracle数据库库 我在C# 为什么Oracle.ManagedDataAccess不工作,而Oracle.DataAccess不工作?,c#,oracle,tnsnames,C#,Oracle,Tnsnames,我正在开发一个非常简单的应用程序,我打算用它来解决我在一些机器上遇到的一个问题,但在我达到这个程度之前,我遇到了一些问题,包括cpu体系结构的差异和Oracle数据库库 我在tnsnames.ora中列出了一个数据库服务器,它位于我的C:\oracle\11g\network\admin目录中。如果我打开这个服务器,我会得到想要的响应。如果我使用Oracle.DataAccess.Client用以下代码编写C#程序以连接到此服务器,它就可以工作 string connectionString =
tnsnames.ora
中列出了一个数据库服务器,它位于我的C:\oracle\11g\network\admin
目录中。如果我打开这个服务器,我会得到想要的响应。如果我使用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:网络传输:无法解析连接主机名
为什么会这样?这两个库之间有什么不同,因为根据我到目前为止所阅读的内容,这不应该是一个问题
额外资料:
- %ORACLE_HOME%和%TNS_ADMIN%未定义(请记住,tnsping和ORACLE.DataAccess可以工作)
- 路径已定义
C:\oracle\11g\BIN
- 我的机器只有一个
tnsnames.ora
文件
如果我将tnsnames.ora移动到与.exe文件相同的位置,它就会工作。为什么Oracle.DataAccess可以在C:\Oracle\11g\network\admin
目录中找到tnsnames.ora,但Oracle.ManagedAccess无法找到?尝试将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>
在ODP.NET托管驱动程序中解析TNS名称的优先顺序如下(请参阅):
.NET配置文件第节下的“数据源”部分中的数据源别名
tnsnames.ora文件中的数据源别名,位于.NET配置文件中“TNS_ADMIN”指定的位置
tnsnames.ora文件中的数据源别名与.exe位于同一目录中
tnsnames.ora文件中的数据源别名位于%TNS_ADMIN%(其中%TNS_ADMIN%是一个环境变量设置)
tnsnames.ora文件中的数据源别名位于%ORACLE\u HOME%\network\admin(其中%ORACLE\u HOME%是一个环境变量设置)李>
我相信,您的示例可以与Oracle.DataAccess一起使用,但不能与Oracle.ManagedDataAccess一起使用的原因是后者不支持基于Windows注册表的配置(请参阅)-ODP.NET安装设置Oracle\u主注册表项(HLKM\SOFTWARE\Oracle\key\u NAME\Oracle\u HOME)它只被非托管部分识别。我有类似的问题……为了解决这个问题,我做的是卸载ODP。Net并重新安装到与oracle server相同的目录中……使用服务器选项,您会注意到大多数产品都已安装(而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);
}
}
/////////下面的代码是来自oracle公司的示例////////////////
使用制度;
使用System.Collections.Generic;
使用系统组件模型;
使用系统数据;
使用System.Data.Common;
使用系统图;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
使用System.Windows.Forms;
使用Oracle.ManagedDataAccess.Client;
///在按钮单击事件中复制这些行
string constr=“用户Id=系统;密码=管理器;数据源=orcl;”;
//单击此处,然后按F9插入断点
DbProviderFactory工厂=
dbProviderFactorys.GetFactory(“Oracle.ManagedDataAccess.Client”);
使用(DbConnection conn=factory.CreateConnection())
{
conn.ConnectionString=CONT;
尝试
{
conn.Open();
OracleCommand cmd=(OracleCommand)factory.CreateCommand();
cmd.Connection=(OracleConnection)conn;
//获取对表的ROWIDs的访问权限
//cmd.AddRowid=true;
cmd.CommandText=“从所有用户中选择*”;
OracleDataReader=cmd.ExecuteReader();
int visFC=reader.VisibleFieldCount;//结果为2
int hidFC=reader.HiddenFieldCount;//结果为1
MessageBox.Show(“可见字段计数:”+visFC);
显示(“隐藏字段计数:+hidFC”);
reader.Dispose();
cmd.Dispose();
}
捕获(例外情况除外)
{
MessageBox.Show(例如Message);
MessageBox.Show(例如StackTrace);
}
}
我收到了相同的错误消息。为了解决这个问题,我刚刚用旧的Oracle.DataAccess
程序集替换了Oracle.ManagedDataAccess
程序集。如果您需要在新部件中找到新功能,此解决方案可能不起作用。在我的例子中,我遇到了更多更高优先级的问题,然后尝试配置新的Oracle
程序集。一旦我在连接字符串中找到了它所要的格式,它就可以像Oracle.ManagedDataAccess这样正常工作。不需要单独处理任何事情
DATA SOURCE=DSDSDS:1521/ORCL;
为了避免Oracle不知道在哪里寻找TNSNAMES.ORA的混乱局面(我增加了多个Oracle ve的混淆)
DSDSDS=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(Host=DSDSDSHost)(Port=4521)))(CONNECT_DATA=(SERVICE_NAME=DSDSDSService)))