without net manageddataaccess example conexion cadena c# oracle tnsnames

net - oracle connection c#



¿Por qué Oracle.ManagedDataAccess no funciona cuando Oracle.DataAccess lo hace? (6)

Estoy desarrollando una aplicación muy simple que pretendo utilizar para solucionar un problema que tengo en algunas máquinas, pero antes de llegar tan lejos me encontré con algunos problemas, incluidas las diferencias de arquitectura de CPU y las bibliotecas de bases de datos de Oracle.

Tengo un servidor de base de datos listado en tnsnames.ora , sentado en mi directorio C:/oracle/11g/network/admin . Si hago tnsping este servidor, obtengo la respuesta deseada. Si codigo mi programa C # para conectarme a este servidor con el siguiente código usando Oracle.DataAccess.Client, funciona.

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

Sin embargo, Oracle.DataAccess depende de la arquitectura del sistema en el que se ejecuta. Vi que hay otra biblioteca Oracle.ManagedDataAccess que es independiente de la arquitectura. Cuando uso esta biblioteca, ya no puedo conectarme al servidor. Un ORA-12545: Network Transport: Unable to resolve connect hostname .

¿Por qué es este el caso? Lo que es diferente entre estas dos bibliotecas porque basado en lo que he leído hasta ahora, esto no debería ser un problema.

Información extra:

  • % ORACLE_HOME% y% TNS_ADMIN% NO están definidos (recuerde que tnsping y Oracle.DataAccess funcionan)
  • PATH tiene definido C:/oracle/11g/BIN .
  • Mi máquina solo tiene un archivo tnsnames.ora

Si muevo tnsnames.ora a la misma ubicación que mi archivo .exe, funciona. ¿Por qué Oracle.DataAccess puede encontrar tnsnames.ora en el directorio C:/oracle/11g/network/admin pero Oracle.ManagedAccess no?


El orden de precedencia para resolver nombres TNS en ODP.NET, controlador administrado es esto (ver here ):

  1. alias del origen de datos en la sección ''dataSources'' en la sección en el archivo de configuración .NET.
  2. alias del origen de datos en el archivo tnsnames.ora en la ubicación especificada por ''TNS_ADMIN'' en el archivo de configuración .NET.
  3. alias de origen de datos en el archivo tnsnames.ora presente en el mismo directorio que el .exe.
  4. alias de fuente de datos en el archivo tnsnames.ora presente en% TNS_ADMIN% (donde% TNS_ADMIN% es una configuración de variable de entorno).
  5. alias de fuente de datos en el archivo tnsnames.ora presente en% ORACLE_HOME% / network / admin (donde% ORACLE_HOME% es una configuración de variable de entorno).

Creo que la razón por la que su ejemplo funciona con Oracle.DataAccess pero no con Oracle.ManagedDataAccess es que la configuración basada en el registro de Windows no es compatible con esta última (ver documentation ) - la instalación de ODP.NET establece una clave de registro ORACLE_HOME (HLKM / SOFTWARE / Oracle / Key_NAME / ORACLE_HOME) que solo es reconocido por la parte no administrada.


Intenta agregar la ruta a tnsnames.ora al archivo de configuración:

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


Para evitar todo el lío de Oracle de no saber dónde está buscando TNSNAMES.ORA (tengo la confusión adicional de varias versiones de Oracle y 32/64 bits), puede copiar la configuración de su TNSNAMES.ORA existente a su propia configuración archivar y usar eso para su conexión.
Digamos que está contento con la referencia ''DSDSDS'' en TNSNAMES.ORA que se asigna a algo como:

DSDSDS=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(Host=DSDSDSHost)(Port=4521)))(CONNECT_DATA=(SERVICE_NAME=DSDSDSService)))
Puede tomar el texto después del primer ''='' y usarlo donde quiera que esté usando ''DSDSDS'' y no necesitará encontrar TNSNAMES.ORA para saber cómo conectarse.
Ahora su cadena de conexión se vería así:
string connectionString = "Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(Host=DSDSDSHost)(Port=4521)))(CONNECT_DATA=(SERVICE_NAME=DSDSDSService)));User Id=UNUNUN;Password=PWPWPW;";


Recibí el mismo mensaje de error. Para resolver esto, simplemente reemplacé el ensamblaje Oracle.DataAccess con el ensamblaje Oracle.DataAccess más Oracle.DataAccess . Es posible que esta solución no funcione si necesita nuevas funciones que se encuentran en el nuevo ensamblaje. En mi caso, tengo muchos más problemas de mayor prioridad que intentar configurar el nuevo ensamblaje de Oracle .


Tuve el problema similar ... para resolver esto, lo que hice fue desinstalar el ODP. Net y vuelva a instalar en el mismo directorio que el servidor Oracle ... con la opción del servidor notará que la mayoría de los productos ya están instalados (mientras que la instalación de la base de datos 12c) así que solo seleccione las otras características y finalmente termine la instalación. ...

Tenga en cuenta que esta solución alternativa solo funciona si ha instalado 12c en la misma máquina, es decir, en su computadora portátil ............

Si su base de datos se encuentra en la máquina del servidor que no sea su computadora portátil, seleccione la opción del cliente y no el servidor y luego incluya TNS_ADMIN en su app.config y no se olvide de especificar la versión ...

desde que mi instalación está en mi computadora portátil, mi App.config es la siguiente:

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


Una vez que encontré el formato que estaba buscando en la cadena de conexión, funcionó muy bien así con Oracle.ManagedDataAccess. Sin tener que perder el tiempo con nada por separado.

DATA SOURCE=DSDSDS:1521/ORCL;