[EF + Oracle] Insertando en la Base de Datos (Secuencias) (2/2)

Prologo

En el episodio anterior hemos visto una forma de crear registros con EF, ahora vamos a ver peculiaridades de ORACLE.

ORACLE

Una característica que posee SQL Server con respecto de Oracle es “Identity”.

Para todos aquellos que no han trabajado con SQL Server, esta propiedad, que aplica a columnas del Tipo Integer permite definirlas como Autoincreméntales, de esa manera se van a rellenar de forma automática, sin tener que especificar la sentencia de inserción a la Base de Datos.

En Entity Framework contra SQL Server, las propiedades que son de este tipo, no se tienen que rellenar tampoco, porque se auto rellenan en SQL Server.

En Oracle, no se dispone directamente de está característica, pero se puede lograr algo parecido.

Secuencias

Las secuencias son objetos de la Base de Datos, que nos permiten generar auto incrementos, pero que no se asocian directamente a una Tabla de la BD.

   1: CREATE SEQUENCE nombre_secuencia

   2: INCREMENT BY numero_incremento 

   3: START WITH numero_por_el_que_empezara 

   4: MAXVALUE valor_maximo | NOMAXVALUE 

   5: MINVALUE valor_minimo | NOMINVALUE 

   6: CYCLE | NOCYCLE 

   7: ORDER | NOORDER

   8:  

La sintaxis para definir una secuencia en Oracle es la que se indica arriba, se define con un nombre, un valor mínimo y un valor máximo y el valor en el que empieza.

¿Como se obtiene el valor de la secuencia?

Para poder obtener el próximo valor de la serie, es necesario ejecutar una consulta SQL:

   1: SELECT nb_secuencia.Nextval 

   2: From Dual

Ya que no se puede asociar de forma directa una secuencia a una columna de la Tabla, se puede optar por utilizar un Trigger Antes de la inserción del Registro y ejecutar la sentencia, o, una opción que se me ha ocurrido:

Puesto que el modelo de EF importa solo los objetos de Tipo Tabla o Procedimientos Almacenados / Funciones, he decidido crear un método extensor:

 

   1: public static class EFSequence 

   2:     {

   3:         public static int GetNextValue(this ObjectContext contexto, string SequenceName) 

   4:         {

   5:             string Connection = ConfigurationManager.ConnectionStrings["JTorrecillaEntities2"].ConnectionString;

   6:             Connection=Connection.Substring(Connection.IndexOf(@"connection string=")+19);

   7:             Connection = Connection.Remove(Connection.Length - 1, 1);

   8:             using (IDbConnection con = new Oracle.DataAccess.Client.OracleConnection(Connection))

   9:             {

  10:                 using (IDbCommand cmd = con.CreateCommand())

  11:                 {

  12:                     con.Open();

  13:                     cmd.CommandText = String.Format("Select {0}.nextval from DUAL", SequenceName);

  14:                     return Convert.ToInt32(cmd.ExecuteScalar());

  15:                 }

  16:             }

  17:  

  18:          }

  19:     }

Este método extensor del ObjectContext,  va a realizar la consulta arriba indicada con el nombre de la Secuencia indicada en el parámetro “SequenceName”. Lee la cadena de conexión generada en el fichero de configuración a la hora de crear el modelo de EF, y le quita la información de metadata sobrante. Devolviendo el siguiente valor disponible de la secuencia.

El valor de la secuencia es único, por lo tanto, a la hora de tener usuarios concurrentes al crear nuestras claves con un valor de la secuencia no se van a duplicar.

Esta implementación es propia, es decir, se que hay otras formas y se que no es la más correcta de hacerla, si encuentro una mejor o se me ocurre otra la posteare.

PD: Para poder usar el método extensor, es necesario que en el proyecto referencia a la DLL de Oracle, que encontrareis en el directorio BIN. Escoged la DLL para .NET 4.0

3 comentarios sobre “[EF + Oracle] Insertando en la Base de Datos (Secuencias) (2/2)”

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *