sábado, 12 de mayo de 2012

Ejecutar un Procedimiento almacenado con Entity Framework


Los procedimientos almacenados son rápidos y encapsulan la lógica del negocio, por lo que es recomendables utilizarlos.


1.) Inicie el SQL Management Studio y ejecute el siguiente codigo para crear un Stored Procedure:

CREATE PROC [dbo].[Getorder] @ProductId INT = NULL
AS
    SELECT a.orderid,
           a.productid,
           b.productname,
           a.unitprice,
           a.quantity,
           a.unitprice * a.quantity AS Total
    FROM   [Order Details] a,
           products b
    WHERE  a.productid = b.productid
           AND ( ( @ProductId IS NULL )
                  OR ( a.ProductId = @ProductId ) ) 


2.)  Para verificar que el Stored Procedure funciona,  ejecute:

EXEC Getorder 1 

3.)  Cree un nuevo site en Visual Studio .net

3.1) File New Site



3.2) Selecciones ASP. Net Empty web Site

4.) Ahora vamos a crear un EDM

4.1) Clic derecho en su Solution explorer:



4.2) Seleccione ADO.Net Entity Data Model y coloque el nombre de: Northwind.edmx



5.) Seleccione "Generate from database"  y seleccione Next



6.) Seleccione Yes, Include the sensitive data in the connection string, esto con la idea de almacenar la clave en el web config.


7.) En Store Procedures selecciones "GetOrder"



8.) Click derecho en el EDM, y seleccionar Add/Function Import



9.) En la ventana de exportación, vamos a crear un método para llamar al store procedure

9.1) Nombre de la función: LlenarOrdenes
9.2) GetOrder
9.3) Presione clic en "Get Column Information"
9.4) Presione clic en "Create New Complex Type"

Si la botón de "OK" no esta habilitado es por que algún paso anterior falto.



Vamos a Crear un pagina que utilice su procedimiento almacenado

10.) Crear un pagina nueva, para esto precione clic derecho en el proyecto y seleccione new Item.


10.1) Seleccione web Form con el nombre Default.aspx



11.) Abra la pagina Default.aspx que acaba de crear y agregue un gridview

11.1) Arraste GridView del toolbox




12.) Vamos agregar código para llenar el gridview, clic derecho en la pagina y luego "view Code"



13.) Agregue el siguiente código para llenar la pantalla:

protected void Page_Load(object sender, EventArgs e)
    { 
        if (!Page.IsPostBack) 
        { 
    NorthwindModel.NorthwindEntities db = new NorthwindModel.NorthwindEntities();
            
            var query = db.LlenarOrdenes(null); 

            GridView1.DataSource = query; 
            GridView1.DataBind(); 
        } 
    }


Precione F5 para ejecutar el proyecto, el resultado será el siguiente:


Vamos a reutilizar el Procedimiento almacenado.

14.) Agregaremos una columna al grid para poder seleccionar un elemento.

14.1) Seleccione el GridView
14.2) Presione la fleche en la esquina superior derecha
14.3) Seleccione Add new Column, llenela con la siguiente información

15.) Llene la ventana con la siguiente información.



16.) Vamos agregar código al botón de ver ordenes, Doble click sobre el GridView, para crear el evento SelectedIndexChanged , agregue el siguiente codigo.
 
 protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
    { 
        GridViewRow row; 
        row = GridView1.SelectedRow; 

        Session["productid"] = row.Cells[1].Text; 
        Response.Redirect("Orders.aspx"); 

    }


17.)Agregue un Nuevo WebForm a su proyecto, con el nombre Orders.aspx

17.1) clic derecho add new Item..





18.) En la pagina orders, agregue un GridView



19.) luego Click derecho, View Code, En el code behind de la pagina Orders, en el evento Load agregue el siguiente codigo:

protected void Page_Load(object sender, EventArgs e)
    { 
    NorthwindModel.NorthwindEntities db = new NorthwindModel.NorthwindEntities();
        int codigo = Convert.ToInt32(Session["productid"]); 
        var query = db.LlenarOrdenes(codigo); 

        GridView1.DataSource = query; 
        GridView1.DataBind(); 
    }

Resultado final:


4 comentarios:

pekation dijo...
Este comentario ha sido eliminado por el autor.
Unknown dijo...

Saludos, me tope con esto por aquí buscando otra cosa, pero esta bien el ejemplo, para el caso de pekation me imagino que casi dos años después ya encontraste la solución, para el que no, lo primero que hay que hacer ejecutar la llamada al procedimiento almacenado a ver que trae, si no trae nada hay que revisar la unión (join) directamente como una consulta normal, si aun así no trae datos es porque debemos de revisar las relaciones de esas tablas, no es lo mismo hacer un INNER JOIN que un LEFT JOIN, se debe de probar con tanto con el LEFT JOIN y con el RIGHT JOIN, pues el INNER JOIN si no hay datos en ambas tablas te la traerá vacía, y si sabes que hay una de esas tablas que tiene datos (si es que hay algún where por hay) debes de utilizar obligaTotira mente un LEFT o RIGHT JOIN.

Unknown dijo...

Buenos dias estoy tratando de hacer un llamado a un sp desde Visual pero me genera error en el return donde no se puede convertir implicitamente el tipo '' en system.colletions.genericlist y la verdad no se si es algo del Sp o algo que este realziando mal .anexo parte del codigo donde me sale este error.



public List GetConsultasListas(string nro_doc)
{

List ConsultasListasRestri = new List();
try
{
var store = StoreProcedureWithOutputParam();
store.SetSqlExec(@"DECLARE @cur_tipo_doc numeric(2,0),
@sn_existe_en_lista si_no,
@sn_lock si_no,
@txt_error VARCHAR(1000),
@txt_listas VARCHAR(600),
@sn_nombres_ok si_no,
@cur_cod_aseg INT ,
@cur_nro_doc VARCHAR(20)");
store.SetSqlExec("EXEC sp_valida_list_restrict_sipla");

store.SetSqlPostExec(@"select @cur_tipo_doc cur_tipo_doc,
@sn_existe_en_lista sn_existe_en_lista,
@sn_lock sn_lock ,
@txt_error txt_error,
@txt_listas txt_listas,
@sn_nombres_ok sn_nombres_ok,
@cur_cod_aseg cur_cod_aseg,
@cur_nro_doc cur_nro_doc");
store.SetCampoScalar(@"cur_tipo_doc,
sn_existe_en_lista ,
sn_lock ,
txt_error,
txt_listas,
sn_nombres_ok,
cur_cod_aseg,
cur_nro_doc");

return store.ExecScalar(new { _out_cur_tipo_doc = 0, _out_sn_existe_en_lista = 0, _out_sn_lock = 0, _out_txt_error = "", _out_txt_listas = "", _out_sn_nombres_ok = 0, _out_cur_cod_aseg = 0, _out_cur_nro_doc = "" });


}
catch (Exception ex)
{
//_logger.RegistrarEventoErrorLog(ex);
throw ex;
}
}

Unknown dijo...

Hola,

Antes que nada, ?Has probado el SP desde sql server? de ser así y te retorna los datos bien, debes de saber que estás intentando entrar toda una consulta en una lista directamente,creo que el list no entiende en concepto de filas y columnas, sino más bien el de items.

Si aún quieres utilizar tu lista debes de hacer recorrer los datos que arroja el SP (foreach) para meter todo en la lista, cosa que sería buena si el SP solo devuelve una fila.

Si ya lo resolviste de todas formas deja aquí como resolviste este tema, asi le sirva a otros.

Un saludo.