Подтвердить что ты не робот

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

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

У меня есть сервер базы данных, указанный в tnsnames.ora, сидящий в моем каталоге C:\oracle\11g\network\admin. Если я набрал этот сервер, я получаю желаемый ответ. Если я закодирую свою программу на С# для подключения к этому серверу со следующим кодом, использующим 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 не может?

4b9b3361

Ответ 1

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

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

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

Ответ 2

Попробуйте добавить путь к 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>

Ответ 3

Чтобы избежать беспорядка в 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;";

Ответ 4

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

DATA SOURCE=DSDSDS:1521/ORCL;

Ответ 5

У меня была аналогичная проблема... для решения этой проблемы я решил удалить 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);
                }
            }

Ответ 6

В моем случае все сказанное выше было в порядке, но я все еще 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

Ответ 7

"Немного" опоздал на вечеринку, но реальный ответ на этот вопрос - если вы используете провайдера 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... DataSource=IP:Port/SID...

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

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

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

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

Ответ 8

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