Почему бы Oracle.ManagedDataAccess не работает, когда Oracle.Доступа к данным делает?

Я разрабатываю очень простое приложение, которое я намерен использовать для устранения неполадок, которые у меня есть на нескольких машинах, но прежде чем я даже получил это далеко, я столкнулся с несколькими проблемами, включая различия в архитектуре процессора и библиотеки баз данных Oracle.

у меня есть сервер базы данных, перечисленных в tnsnames.ora, сидя в своем . Если я tnsping этот сервер, я получаю желаемый ответ. Если я закодирую свою программу 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 зависит от архитектуры системы, в которой он работает. Я видел, что есть еще один библиотечный Оракул.ManagedDataAccess, который не зависит от архитектуры. Когда я использую эту библиотеку, она больше не может подключаться к серверу. Ан ORA-12545: Network Transport: Unable to resolve connect hostname бросается.

почему это произошло? Что отличается между этими двумя библиотеками, потому что на основе того, что я прочитал до сих пор, это не должно быть вопрос.

дополнительная информация:

  • %ORACLE_HOME% и %TNS_ADMIN% не определены (помните, что tnsping и Oracle.Работа DataAccess)
  • путь C:oraclegBIN определенными.
  • моя машина имеет только один

    если я перемещаю tnsnames.Ора в то же место, что и я .EXE-файл, он работает. Почему Оракул.DataAccess найти tnsnames.Ора в C:oraclegnetworkadmin каталог, но Oracle.ManagedAccess не может?

6 ответов


порядок приоритета для разрешения имен TNS в ODP.NET, управляемый драйвер-это (см. здесь):

  1. псевдоним источника данных в разделе "Источники данных" в разделе файла конфигурации .NET.
  2. псевдоним источника данных в файл tnsnames.файл ora в расположении, указанном 'TNS_ADMIN' в файле конфигурации .NET.
  3. псевдоним источника данных в файл tnsnames.файл ora присутствует в том же каталоге, что и файл .исполняемый.
  4. псевдоним источника данных в файла tnsnames.файл ora присутствует в %TNS_ADMIN% (где %TNS_ADMIN% - параметр переменной среды).
  5. псевдоним источника данных в файл tnsnames.файл ora присутствует в %ORACLE_HOME%\network\admin (где %ORACLE_HOME% - параметр переменной среды).

Я считаю, что причина, по которой ваш образец работает с Oracle.DataAccess, но не с Oracle.ManagedDataAccess что реестра, настройки не поддерживается для последнего (см. документация) - ODP.NET установка задает раздел реестра ORACLE_HOME (HLKM\SOFTWARE\Oracle\Key_NAME\ORACLE_HOME), который распознается только неуправляемой частью.


попробуйте добавить путь к 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.2.0\client_1\NETWORK\ADMIN\" />
      </settings>
    </version>
  </oracle.manageddataaccess.client>
</configuration>

чтобы избежать всего беспорядка Oracle, не зная, где он ищет имена TNSNAMES.ORA (у меня есть дополнительная путаница нескольких версий Oracle и 32/64 бит), вы можете скопировать настройку из существующих имен TNSNAMES.ORA к вашему собственному файлу конфигурации и используйте его для вашего соединения.
Скажите, что вы довольны ссылкой "DSDSDS" в TNSNAMES.ORA, которая сопоставляется с чем-то вроде:

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;";

У меня была аналогичная проблема......чтобы решить эту проблему, я удалил ODP. Net и переустановить в том же каталоге, что и сервер oracle......с опцией сервера вы заметите, что большинство продуктов уже установлены (при установке базы данных 12c), поэтому просто выберите другие функции и, наконец, завершите установку....

обратите внимание, что этот метод работает только если вы установили 12C на той же машине, т. е. на ноутбук............

Если ваша база данных находится на сервере, отличном от вашего ноутбука, выберите опцию клиента, а не сервер, а затем включите TNS_ADMIN в свое приложение.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.ManagedDataAccess. Без необходимости возиться с чем-то отдельно.

DATA SOURCE=DSDSDS:1521/ORCL;

я получил то же сообщение об ошибке. Чтобы решить эту проблему, я просто заменил Oracle.ManagedDataAccess сборка со старшим Oracle.DataAccess сборка. Это решение может не работать, если требуются новые функции, найденные в новой сборке. В моем случае у меня есть еще много более приоритетных проблем, чем попытка настроить новый Oracle сборка.