web-dev-qa-db-fra.com

Pourquoi Oracle.ManagedDataAccess ne fonctionne-t-il pas quand Oracle.DataAccess fonctionne?

Je développe une application très simple que je compte utiliser pour résoudre un problème que je rencontre sur quelques machines, mais avant cela, j’avais rencontré quelques problèmes, notamment des différences d’architecture cpu et des bibliothèques de bases de données Oracle.

J'ai un serveur de base de données répertorié dans tnsnames.ora, assis dans mon répertoire C:\Oracle\11g\network\admin. Si je tspsping ce serveur j'obtiens la réponse désirée. Si je code mon programme C # pour me connecter à ce serveur avec le code suivant en utilisant Oracle.DataAccess.Client, cela fonctionne.

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);
        }
    }
}

Cependant, Oracle.DataAccess dépend de l'architecture du système sur lequel il s'exécute. J'ai vu qu'il existe une autre bibliothèque Oracle.ManagedDataAccess indépendante de l'architecture. Lorsque j'utilise cette bibliothèque, il n'est plus possible de se connecter au serveur. Un ORA-12545: Network Transport: Unable to resolve connect hostname est lancé.

Pourquoi est-ce le cas? Ce qui est différent entre ces deux bibliothèques parce que, d'après ce que j'ai lu jusqu'à présent, cela ne devrait pas être un problème.

Informations supplémentaires:

  • % Oracle_HOME% et% TNS_ADMIN% ne sont PAS définis (rappelez-vous que tnsping et Oracle.DataAccess fonctionnent)
  • PATH a C:\Oracle\11g\BIN défini.
  • Ma machine n'a qu'un seul fichier tnsnames.ora

Si je déplace tnsnames.ora au même emplacement que mon fichier .exe, cela fonctionne. Pourquoi Oracle.DataAccess peut-il rechercher tnsnames.ora dans le répertoire C:\Oracle\11g\network\admin alors que Oracle.ManagedAccess ne le peut pas?

35
Rakshasas

L'ordre de priorité pour la résolution des noms TNS dans ODP.NET, Pilote géré est le suivant (voir ici ):

  1. alias de source de données dans la section 'dataSources' sous la section du fichier de configuration .NET.
  2. alias de source de données dans le fichier tnsnames.ora à l'emplacement spécifié par "TNS_ADMIN" dans le fichier de configuration .NET.
  3. alias de source de données dans le fichier tnsnames.ora présent dans le même répertoire que le fichier .exe.
  4. alias de source de données dans le fichier tnsnames.ora présent à% TNS_ADMIN% (où% TNS_ADMIN% est un paramètre de variable d'environnement).
  5. alias de source de données dans le fichier tnsnames.ora présent dans% Oracle_HOME%\network\admin (où% Oracle_HOME% est un paramètre de variable d'environnement). 

Je crois que la raison pour laquelle votre exemple fonctionne avec Oracle.DataAccess mais pas avec Oracle.ManagedDataAccess est que la configuration basée sur le registre Windows n'est pas prise en charge pour ce dernier (voir documentation ) - l'installation ODP.NET définit une clé de registre Oracle_HOME (HLKM\SOFTWARE\Oracle\Key_NAME\Oracle_HOME) qui est reconnu uniquement par la partie non gérée.

51
metalheart

Essayez d’ajouter le chemin vers tnsnames.ora au fichier de configuration:

<?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>
13
kolbasov

Pour éviter tout désordre Oracle de ne pas savoir où il cherche le fichier TNSNAMES.ORA (la confusion de plusieurs versions Oracle et 32/64 bits), vous pouvez copier le paramètre de votre fichier TNSNAMES.ORA existant dans votre propre configuration. déposer et utiliser cela pour votre connexion.
Dites que vous êtes satisfait de la référence 'DSDSDS' dans TNSNAMES.ORA, qui correspond à quelque chose comme:

DSDSDS = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP) = TCP) (hôte = DSDSDSHost) (port = 4521))) (CONNECT_DATA = (SERVICE_NAME = DSDSDSService)))

Vous pouvez prendre le texte après le premier '=' et l'utiliser partout où vous utilisez 'DSDSDS' et il n'aura pas besoin de trouver TNSNAMES.ORA pour savoir comment se connecter.
Maintenant, votre chaîne de connexion ressemblerait à ceci:
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
user3902302

J'ai eu le même problème ...... pour résoudre ce problème, j'ai désinstallé l'ODP. Net et réinstallez-le dans le même répertoire que le serveur Oracle ...... avec l'option de serveur, vous remarquerez que la plupart des produits sont déjà installés (lors de l'installation de la base de données 12c). ...

Veuillez noter que cette solution de contournement ne fonctionne que si vous avez installé 12c sur le même ordinateur, c'est-à-dire sur votre ordinateur portable ............

Si votre base de données est située sur un serveur autre que votre ordinateur portable, veuillez sélectionner l'option client et non le serveur, puis incluez TNS_ADMIN dans votre app.config et n'oubliez pas de spécifier la version ...

depuis mon installation est sur mon ordinateur portable donc mon App.config est comme ci-dessous:

<?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);
                }
            }
1
Siddiqui

Une fois que j'ai trouvé le format recherché dans la chaîne de connexion, cela fonctionnait parfaitement avec Oracle.ManagedDataAccess. Sans avoir à perdre son temps avec quoi que ce soit séparément.

DATA SOURCE=DSDSDS:1521/ORCL;
1
Underground

Dans mon cas, tout était dit ci-dessus, mais je recevais toujours ORA-12545: Network Transport: Unable to resolve connect hostname

J'ai essayé de faire un ping sur la machine Oracle et j'ai découvert que je ne pouvais pas le voir et je l'ai ajouté au fichier hosts. Ensuite, j'ai reçu un autre message d'erreur ORA-12541: TNS:no listener. Après enquête, je me suis rendu compte que cingler le même nom d’hôte de différentes machines obtenant des adresses IP différentes (je ne sais pas pourquoi) et j’ai changé l’adresse IP de mon fichier Host, ce qui a résolu le problème à 100%.

Je prends la peine d'écrire mon expérience car cela semble évident, mais bien que j'étais sûr que le problème se trouvait dans les paramètres ci-dessus, j'avais totalement oublié de vérifier si je pouvais vraiment voir la machine DB distante. N'oubliez pas ce qui se passe lorsque vous êtes à court d'idées.

Ces liens m'ont beaucoup aidé:

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

0
ppenchev