Oracle Data Provider for .NET Core

12 minuto(s) de leitura - February 20, 2018

01

Fala pessoal, tudo bem?! 💚

Minhas primeiras impressões

Recentemente a Oracle divulgou a primeira versão do Oracle Data Provider for .NET Core (Beta), os binários ainda não estão disponíveis no NUGET.
Mas você pode baixar no link abaixo.
http://www.oracle.com/technetwork/topics/dotnet/downloads/odpnetcorebeta-4077982.html


Quero compartilhar com você meu primeiro contato com o Oracle Data Provider for .NET Core (Beta). Praticamente todos recursos estão disponíveis, pelo menos todos que pude testar, mas encontrei um pequeno BUG quando adicionamos parâmetros únicos(um-a-um).

Como consegui reproduzir?!

Criei um pequeno projeto para fazer os testes básicos.

Criando ambiente de teste

Para aqueles que estão familiarizados com ORACLE, abra o prompt de comando e execute o comando abaixo, dentro da pasta BIN, onde seu ORACLE foi instalado.
sqlplus.exe / as sysdba

Execute os comandos abaixo, pode trocar ralms por um nome desejável.

Criando o banco e usuário

CREATE PLUGGABLE DATABASE ralms
   ADMIN USER ralms_admin IDENTIFIED BY ralms_admin
   ROLES = (DBA)
   FILE_NAME_CONVERT = ('\pdbseed\', '\pdb_ralms_01\');

Deixar o banco acessível

ALTER PLUGGABLE DATABASE ralms OPEN;

Deslogar do sysdba

quit

Conectar com o usuário criado

sqlplus ralms_admin/ralms_admin@127.0.0.1:1521/ralms

Aplicar permissões ao usuário

GRANT UNLIMITED TABLESPACE TO ralms_admin;

Requisitos

Acesse AQUI e veja alguns procedimentos que o time do Entity Framework Core solicita para testes do projeto.

Arquivo utilizado!

using Oracle.ManagedDataAccess.Client;
using System;
using System.Data;
using Xunit;

namespace OracleTestesNetCore
{
    public class Testes
    {
        private static OracleConnection _oracleConnection = null;
        private static readonly OracleParameter[] _parametros = new[]
        {
            new OracleParameter
            {
                OracleDbType = OracleDbType.Varchar2,
                ParameterName="DESCRICAO",
                Value = "DESCRICAO TESTE"
            },
            new OracleParameter
            {
                OracleDbType = OracleDbType.Decimal,
                ParameterName="VALOR",
                Value = 25.99m
            },
            new OracleParameter
            {
                OracleDbType = OracleDbType.Date,
                ParameterName="DATA",
                Value = DateTime.Now
            }
        };

        public Testes()
        {
            // Efetuar conexão!
            _oracleConnection = new OracleConnection
            {
                ConnectionString = new OracleConnectionStringBuilder
                {
                    UserID = "ralms_admin",
                    Password = "ralms_admin",
                    DataSource = "127.0.0.1:1521/ralms"
                }.ConnectionString
            };

            _oracleConnection.Open();

            // Inicializar Banco
            InicializarBanco();
        }

        [Fact]
        public void Inserir_Parametro_Um_Por_Um()
        {
            ExecutarComando("DELETE FROM \"TESTE\"");

            for (int i = 0; i < 3; i++)
            {
                ExecutarComando(
                    $"INSERT INTO \"TESTE\" (DESCRICAO,VALOR,DATA) VALUES (:DESCRICAO,:VALOR,:DATA)",
                    _parametros);
            }

            var dados = GetDados("SELECT * FROM \"TESTE\"");

            Assert.True(dados.Rows.Count == 3);
        }

        [Fact]
        public void Inserir_Parametro_Range()
        {
            ExecutarComando("DELETE FROM \"TESTE\"");

            for (int i = 0; i < 3; i++)
            {
                ExecutarComando(
                    $"INSERT INTO \"TESTE\" (DESCRICAO,VALOR,DATA) VALUES (:DESCRICAO,:VALOR,:DATA)",
                    _parametros,
                    true);
            }

            var dados = GetDados("SELECT * FROM \"TESTE\"");

            Assert.True(dados.Rows.Count == 3);
        }

        [Fact]
        public void GetTabelas()
        {
            var dados = GetDados("SELECT * FROM ALL_TABLES");

            Assert.True(dados.Rows.Count > 0);
        }

        private static void InicializarBanco()
        {
            ExecutarComando(
@"BEGIN
  EXECUTE IMMEDIATE 'CREATE TABLE ""TESTE""(
    ""ID"" NUMBER(38, 0) GENERATED BY DEFAULT AS IDENTITY MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER  NOCYCLE  NOKEEP  NOSCALE  NOT NULL ENABLE,
    ""DESCRICAO"" NVARCHAR2(100),
    ""DATA"" DATE,
    ""VALOR"" NUMBER(18, 2)
)';
EXCEPTION
WHEN OTHERS THEN
  RAISE;
END;");

        }

        private static void ExecutarComando(
            string comando,
            OracleParameter[] parametros = null,
            bool usarRange = false)
        {
            using (var cmd = _oracleConnection.CreateCommand())
            {
                cmd.CommandText = comando;

                if (parametros != null)
                {
                    if (usarRange)
                    {
                        cmd.Parameters.AddRange(parametros);
                    }
                    else
                    {
                        for (int i = 0; i < parametros.Length; i++)
                        {
                            cmd.Parameters.Add(parametros[i]);
                        }
                    }
                }
                cmd.ExecuteNonQuery();
            }
        }

        private static DataTable GetDados(string comando)
        {
            var dados = new DataTable();
            using (var cmd = _oracleConnection.CreateCommand())
            {
                cmd.CommandText = comando;
                dados.Load(cmd.ExecuteReader(CommandBehavior.CloseConnection));
                return dados;
            }
        }
    }
}


BUG

O teste Inserir_Parametro_Um_Por_Um falha!

Em uma análise pessoal, acredito que existe um método interno que não está se comportando da forma correta, ou seja, quando utilizado o Parameters.Add pela primeira vez funciona normalmente, mais a partir da segunda gera uma exceção, mesmo criando uma nova instancia da conexão. Ele está armazenando e não está limpando a coleção ao destruir o objeto, causando a seguinte exceção:

“OracleParameter object is already contained in a collection”

Solução

A solução é usar o Parameters.AddRange para suprir temporariamente esse pequeno BUG. já que está funcionando perfeitamente!

Considerações:
Parabéns ORACLE, já foi uma grande iniciativa, esperamos o provider no NUGET!



Pessoal, fico por aqui forte abraço!

Categorias:

Atualizado em:

Deixe um comentário