Llamar un procedimiento almacenado con Entity Framework3 min read

Posted on Posted in Entity Framework, Performance

A veces cuando uno esta utilizando un ORM  es muy común que se tenga la necesidad de ejecutar codigo directamente en la base de datos, por una u otra razón, por esto es importante conocer como llamar un procedimiento almacenado con Entity Framework.

Porque llamar un procedimiento almacenado con Entity Framework?

A veces, cuando se tiene un requerimiento en donde se tiene que realizar algunas validaciones donde involucras diferentes tables, y dependiendo del flujo del código puedes llamar unas tablas, o a otras, o quizá a ninguna, significa que tienes que realizar muchas llamadas a tablas o vistas.

Llamar un procedimiento almacenado de AdventureWorks
Procedimientos almacenados de AdventureWorks

Si lo haces en C# usando Entity Framework, lo mas probable es que termines haciendo varios viajes a la base de datos, lo cual hace mas lenta la respuesta de tu sistema, esto puedes verificarlo usando MiniProfiler. Esto se soluciona si el proceso lo pasas directamente al servidor de base de datos, e incluso si tuvieras que usar alguna transacción para asegurar la integridad de los datos, hacerlo directamente en tu DB facilita mucho esto.

Otro beneficio es que en caso de que tengas que cambiar rápidamente el flujo o algunos resultados, puedes hacerlo cómodamente actualizando el procedimiento almacenado desde cualquier equipo donde tengas algún sistema para conectarte a la DB, de otra forma, tienes que llegar tu PC, modificar, compilar y subir el código a tu servidor web. Y ni hablar de actualizar un sistema de escritorio donde llamas directamente a la DB.

Como llamar un procedimiento almacenado con Entity Framework

Lo primero que tienes que saber es que vamos a usar la conexión existente (objeto DBContext) en nuestra aplicacion, es decir la misma que normalmente usas para acceder a las tablas usuario, ej. db.Usuario, es decir usaremos nuestro objeto llamado comúnmente “db”.

Hay dos formas de llamar a un procedimiento almacenado desde Entity Framework, una es si quieres que regrese algún resultado y otra es que no regrese nada.

Llamar un procedimiento almacenado sin que regrese nada

Por ejemplo si necesitas hacer un proceso que no te regresa ningún resultado, solamente tienes que ejecutar el siguiente código:

db.Database.ExecuteSqlCommand("EXEC NombreDelProcedimientoAlmacenado @p0, @p1, @p2", 
    "Ejemplo",     // Valor 1er parametro: @p0
    12345678,      // Valor 1er parametro: @p1
    DateTime.Now); // Valor 2do parametro: @p2

En donde:

  • NombreDelProcedimientoAlmacenado: es el nombre de tu procedimiento
  • @p0, @p1 y @p2: son los parametros que se ligaran a los que tu tienes en tu procedimiento, tus parámetros no se tienen que llamar @p0 o @p1, se pueden llamar como tu quieras dentro de tu procedimiento, peeeero si tienen que estar en el mismo orden en el que estas asignando su valor en C#, esto lo utliza EF como un tipo de ayuda para no escribir el nombre completo de tu parámetro y ligarlo manualmente, tambien muy importante para evitar que escribas el valor directamente en el query y sufras un ataque SQL Injection

Recapitulando el ultimo punto, si en tu procedimiento almacenado tienes 5 parametros, entonces tendras desde @p0 hasta @p4, y si tu primer parámetro se llama UserName y es tipo VARCHAR() entonces tu primer parámetro (@p0) en el metodo ExecuteSqlCommand después del texto de “EXEC …..” sera tu valor para ese parámetro

Llamar un procedimiento almacenado regresando un resultado

Básicamente se siguen las mismas reglas que arriba pero ahora, se llama otro método, el cual tendremos que indicarle la clase que va a usar para mapear el resultado que regrese, es decir, tal y como EF, le diremos que clase usar como modelo para nuestro resultado:

var resultado = db.Database.SqlQuery<ClaseModelo>("EXEC NombreDelProcedimientoAlmacenado @p0, @p1, @p2", 
    "Ejemplo",     // Valor 1er parametro: @p0
    12345678,      // Valor 1er parametro: @p1
    DateTime.Now); // Valor 2do parametro: @p2     

En donde:

  • ClaseModelo: es la clase con las propiedades que usara EF para mapear las filas que regrese el procedimiento almacenado
  • resultado: es la variable que contiene las filas regresadas por el procedimiento, podemos usar Linq o un foreach para recorrerlas en caso de que lo necesitemos.