Oracle.DataAccess为什么Oracle.ManagedDataAccess不起作用?

时间:2013-07-03 18:56:19

标签: c# oracle tnsnames

我正在开发一个非常简单的应用程序,我打算用它来解决我在几台机器上遇到的问题,但在我到目前为止,我遇到了一些问题,包括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: 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不能找到?

8 个答案:

答案 0 :(得分:55)

在ODP.NET,托管驱动程序中解析TNS名称的优先顺序是这样的(参见here):

  1. .NET配置文件中“dataSources”部分下的数据源别名。
  2. 在.NET配置文件中由“TNS_ADMIN”指定的位置的tnsnames.ora文件中的数据源别名。
  3. tnsnames.ora文件中的数据源别名,与.exe。在同一目录中。
  4. %TNS_ADMIN%中存在的tnsnames.ora文件中的数据源别名(其中%TNS_ADMIN%是环境变量设置)。
  5. %ORACLE_HOME%\ network \ admin中的tnsnames.ora文件中的数据源别名(其中%ORACLE_HOME%是环境变量设置)。
  6. 我相信您的示例使用Oracle.DataAccess而不使用Oracle.ManagedDataAccess的原因是后者不支持基于Windows注册表的配置(请参阅documentation) - ODP.NET安装设置ORACLE_HOME注册表密钥(HLKM \ SOFTWARE \ Oracle \ Key_NAME \ ORACLE_HOME),仅由非托管部件识别。

答案 1 :(得分:13)

尝试将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>

答案 2 :(得分:4)

为了避免所有Oracle不知道它在哪里寻找TNSNAMES.ORA(我有多个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;";

答案 3 :(得分:2)

一旦我找到它在连接字符串中寻找的格式,它就像使用Oracle.ManagedDataAccess一样正常。无需单独处理任何事情。

DATA SOURCE=DSDSDS:1521/ORCL;

答案 4 :(得分:1)

我有类似的问题......要解决这个问题,我所做的就是卸载ODP。网络并重新安装在与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);
                }
            }

答案 5 :(得分:0)

就我而言,上述所有内容都可以,但是我仍然收到ORA-12545: Network Transport: Unable to resolve connect hostname

我尝试对Oracle计算机执行ping操作,发现我看不到它并将其添加到hosts文件中。然后,我收到另一个错误消息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

答案 6 :(得分:0)

晚了一点,但是真正的答案-如果您使用Oracle.ManagedDataAccess ODP.NET提供程序,则应该忘记诸如network\adminOracle client,{ {1}},等等。

这就是您需要的

  1. 下载并安装 Oracle Developer Tools for VS ODAC 。注意-开发工具将为您安装ODAC。这将在Oracle_Home下创建相对较小的安装。拥有完整的开发工具,低于60Mb
  2. 在您的项目中,您将安装Nuget软件包以及相应的ODP.net (Oracle.ManagedDataAccess.dll)版本
  3. 这时您有2个连接选项。

    • a)在连接字符串中,将C:\Program Files (x86)设置为以下格式

      datasourceDataSource=ServerName:Port/SID . . .

    • b)创建DataSource=IP:Port/SID . . .文件(只是它将与以前的经验有所不同)。在其中输入:

        

      AAA =(DESCRIPTION =
               (地址=(协议= TCP)(主机= ServerNameOrIP)(端口= 1521))
               (CONNECT_DATA =(服务器=专用)(SERVICE_NAME = SIDNAME)))

      将此文件放置到运行应用程序的bin文件夹中。 现在,您可以使用连接名称-tnsnames.ora进行连接,因此,即使您拥有 tnsnames.ora ,但ODP.net 托管的工作方式也有所不同-您创建本地TNS文件。现在,它很容易管理。

总结一下-使用托管,不需要笨拙的Oracle Client,DataSource=AAA . . .或知道oracle安装文件夹的深度。一切都可以在.net应用程序结构中完成。

答案 7 :(得分:-2)

我收到了同样的错误消息。要解决此问题,我只是将Oracle.ManagedDataAccess程序集替换为较旧的Oracle.DataAccess程序集。如果您需要在新装配中找到新功能,则此解决方案可能无效。在我的情况下,我有更多更高优先级的问题,然后尝试配置新的Oracle程序集。