Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么Oracle.ManagedDataAccess不工作,而Oracle.DataAccess不工作?_C#_Oracle_Tnsnames - Fatal编程技术网

C# 为什么Oracle.ManagedDataAccess不工作,而Oracle.DataAccess不工作?

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 =

我正在开发一个非常简单的应用程序,我打算用它来解决我在一些机器上遇到的一个问题,但在我达到这个程度之前,我遇到了一些问题,包括cpu体系结构的差异和Oracle数据库库

我在
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)))