Почему Oracle.ManagedDataAccess не работает, когда Oracle.DataAccess работает?

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

У меня есть сервер базы данных, указанный в tnsnames.ora, сидя в моем C:\oracle\11g\network\admin каталог. Если я использую этот сервер, я получаю желаемый ответ. Если я кодирую свою программу на C# для подключения к этому серверу с помощью следующего кода, используя Oracle.DataAccess.Client, это работает.

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 может найти tnsnames.ora в C:\oracle\11g\network\admin каталог, но Oracle.ManagedAccess не может?

9 ответов

Решение

Порядок приоритетов для разрешения имен TNS в ODP.NET, управляемом драйвере, выглядит следующим образом (см. Здесь):

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

Я полагаю, что причина, по которой ваш пример работает с Oracle.DataAccess, но не с Oracle.ManagedDataAccess, заключается в том, что конфигурация на основе реестра Windows не поддерживается для последнего (см. Документацию) - при установке 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\10.2.0\client_1\NETWORK\ADMIN\" />
      </settings>
    </version>
  </oracle.manageddataaccess.client>
</configuration>

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

 DSDSDS = (ОПИСАНИЕ =(ADDRESS_LIST=(АДРЕС = (ПРОТОКОЛ =TCP)(Хост = DSDSDSHost) (Порт =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;";

Как только я нашел, какой формат он искал в строке подключения, он прекрасно работал с Oracle.ManagedDataAccess. Без необходимости возиться с чем-то отдельно.

DATA SOURCE=DSDSDS:1521/ORCL;

"Немного" опоздал на вечеринку, но реальный ответ на это - если вы используете Oracle.ManagedDataAccess Поставщик ODP.NET, вы должны забыть о таких вещах, как network\admin, Oracle client, Oracle_Home, так далее.

Вот что вам нужно

  1. Загрузите и установите Oracle Developer Tools для VS или ODAC. Примечание. Dev Tools установит ODAC для вас. Это создаст относительно небольшую установку под C:\Program Files (x86), С полным набором инструментов, до 60 Мб
  2. В вашем проекте вы установите пакет Nuget с соответствующей версией ODP.net (Oracle.ManagedDataAccess.dll), на которую вы будете ссылаться
  3. На данный момент у вас есть 2 варианта подключения.

    • а) В строке подключения установлено datasource в следующем формате

      DataSource=ServerName:Port/SID . . . или же DataSource=IP:Port/SID . . .

    • б) Создать tnsnames.ora файл (только он будет отличаться от предыдущего опыта). Есть запись в нем:

      AAA = (ОПИСАНИЕ =
      (ADDRESS = (PROTOCOL = TCP) (HOST = ServerNameOrIP) (PORT = 1521))
      (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = SIDNAME)))

      И поместите этот файл в папку bin, откуда запускается ваше приложение. Теперь вы можете подключиться, используя ваше имя подключения - DataSource=AAA . . . Итак, несмотря на то, что у вас есть tnsnames.ora, с ODP.net он работает немного по-другому - вы создаете локальный файл TNS. И теперь им легко управлять.

Подводя итог - с управляемым, нет необходимости в тяжелом клиенте Oracle, Oracle_home или зная глубину папок установки оракула. Все может быть сделано в ваших структурах приложений.net.

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

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

Если ваша база данных расположена на сервере, отличном от вашего ноутбука, выберите вариант клиента, а не сервер, а затем включите TNS_ADMIN в ваш файл app.config и не забудьте указать версию...

так как моя установка на моем ноутбуке, поэтому мой 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.ManagedDataAccess и оставление только Oracle.ManagedDataAccess.Core работает для меня.

В моем случае все сказанное выше было в порядке, но я все еще получал ORA-12545: Network Transport: Unable to resolve connect hostname

Я попытался пропинговать машину Oracle и обнаружил, что не вижу ее, и добавил ее в файл hosts. Затем я получил еще одно сообщение об ошибке ORA-12541: TNS:no listener, После исследования я понял, что пинг одного и того же имени хоста с разных компьютеров получает разные IP-адреса (я не знаю почему), и я изменил IP-адрес в файле хоста, что решило проблему на 100%.

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

Эти ссылки мне очень помогли:

http://www.moreajays.com/2013/03/ora-12545-connect-failed-because-target.html http://www.orafaq.com/wiki/ORA-12541

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

Другие вопросы по тегам