Ahora revisaremos el tema de procedimientos almacenados y LINQ TO SQL. Para este demo usare la tabla TB_USUARIO de la base de datos VentasDemo. La tabla en cuestión tiene la siguiente estructura:
1: CREATE TABLE [Tb_Usuario](
2: [COD_USU] [nvarchar](3) NOT NULL Primary Key,
3: [LOG_USU] [nvarchar](12) NULL,
4: [PAS_USU] [nvarchar](12) NULL)
1: Create Procedure VT_Usuario_Get01
2: as
3: Select * From TB_usuario
4:
5: Create Procedure VT_Usuario_INS
6: @CodUsu char(3),
7: @LogUsu varchar(15),
8: @PasUsu varchar(15)
9: as
10: Insert into TB_Usuario Values(@CodUsu,@LogUsu,@PasUsu)
11:
12:
13: Create Procedure VT_USUARIO_UPD
14: @CODUSU CHAR(3),
15: @LOGUSU VARCHAR(12),
16: @PASUSU VARCHAR(12)
17: AS
18: UPDATE TB_USUARIO SET
19: LOG_USU=@LOGUSU,
20: PAS_USU=@PASUSU
21: WHERE COD_USU=@CODUSU
22:
23: Create Procedure VT_USUARIO_DEL
24: @CodUsu char(3)
25: as
26:
27: Delete From TB_Usuario Where Cod_Usu=@CodUsu
Relacionamos los parámetros del SP con los argumentos del método:
Listo!!! hasta aquí ya se tiene el DataContext y los procedimientos almacenados debidamente relacionados con los métodos generados por LINQ. Para probarlo he diseñado esta interface:
Por último el código de cada botón:
1: Private Sub btnInsertar_Click(ByVal sender As System.Object, _
2: ByVal e As System.EventArgs) Handles btnInsertar.Click
3:
4: Dim dc As New VentasDemoDataContext
5:
6: Dim UsuarioBE As New Tb_Usuario
7: With {.COD_USU = txtCodUsuario.Text, _
8: .LOG_USU = txtUser.Text, _
9: .PAS_USU = txtPass.Text}
10:
11: dc.Tb_Usuarios.InsertOnSubmit(UsuarioBE)
12: Try
13: dc.SubmitChanges()
14: MessageBox.Show("Se inserto")
15: Catch ex As Exception
16: MessageBox.Show(ex.Message)
17: End Try
18:
19: End Sub
Se crea una instancia de la entidad TB_Usuario, luego se carga de los datos y paso siguiente se llama al método InsertOnSubmit pasando como parámetro nuestra entidad UsuarioBE. Finalmente, se ejecuta el metodo SubmiChanges de nuestro DataContext para almacenar los datos.
Para las actualización y eliminación el código es muy parecido:
1: Private Sub btnEditar_Click(ByVal sender As System.Object, _
2: ByVal e As System.EventArgs) Handles btnEditar.Click
3:
4: Dim dc As New VentasDemoDataContext
5: Dim UsuarioBE = (From BE In dc.Tb_Usuarios _
6: Where BE.COD_USU = txtCodUsuario.Text).Single
7:
8:
9: With UsuarioBE
10: .LOG_USU = txtUser.Text.Trim
11: .PAS_USU = txtPass.Text.Trim
12: End With
13:
14: dc.Log = Console.Out
15:
16: Try
17: dc.SubmitChanges()
18: MessageBox.Show("Se actualizo")
19: Catch ex As Exception
20: MessageBox.Show(ex.Message)
21: End Try
22: End Sub
1: Private Sub btnEliminar_Click(ByVal sender As System.Object, _
2: ByVal e As System.EventArgs) Handles btnEliminar.Click
3:
4: Dim dc As New VentasDemoDataContext
5: Dim UsuarioBE = (From BE In dc.Tb_Usuarios Where _
6: BE.COD_USU = txtCodUsuario.Text).Single
7:
8: dc.Tb_Usuarios.DeleteOnSubmit(UsuarioBE)
9: Try
10: dc.SubmitChanges()
11: MessageBox.Show("Se elimino")
12: Catch ex As Exception
13: MessageBox.Show(ex.Message)
14: End Try
15: End Sub
Para realizar una consulta, ejecutamos desde el DataContext el método VT_Usuario_GET01, este es nuestro procedimiento almacenado.
1: Private Sub btnVer_Click( _
2: ByVal sender As System.Object, _
3: ByVal e As System.EventArgs) Handles btnVer.Click
4:
5: Dim dc As New VentasDemoDataContext
6:
7: DataGridView1.DataSource = dc.VT_Usuario_Get01
8: End Sub
Que simpático!, pero que paso con las consultas integradas como:
1: Dim Result = From BE In dc.TB_Usuario
esa es la parte fea, si usamos los procedimientos almacenados para realizar las consultas, perdemos la funcionalidad del lenguaje integrado ya que este se genera de forma dinámica.
Para el próximo capítulo, revisare como LINQ TO SQL maneja las transacciones y aplicaciones N-Capas
Saludos :)

5 comentarios:
Entonces quiere decir que al usar Linq, no es recomendable hacer: "instanciaLinq.StoreProc" para traer datos o para realizar alguna inserción, actualización, etc? y es porque el lenguaje integrado se va a generar de todas maneras. Es asi o es que eso solo se da cuando se realizan consultas?.
Hola, si usas las consultas integradas siempre se va a generar el transact-sql dinámico tanto para operaciones de consultas, inserción, actualización y eliminación. Si usas procedimientos almacenados, como lo explico en el artículo, LINQ usara los SP y no genera el transact-sql dinamicamente. Podemos usar los dos, por ejemplo para las operaciones de insertar, editar y eliminar usamos SP, y para las consultas usamos el LINQ.
Hola, pero habria una razon para usar SP's con LINQ?. Suponiendo que no hay restricciones en BD y sabiendo que los LINQ Queries (compilados) son tan rapidos como los SP's, por que habria de usar SP's con LINQ entonces?. Lo unico que se me viene a la cabeza es para el mantenimiento, osea que es mejor cambiar un solo SP a cambiar todas los LINQ queries. Yo creo que si es bueno usar SP para hacer logica al Insertar, Update, Delete .... y tambien es bueno usar SP's en Selects cuando tenemos repetidas consultas de lo mismo en diferentes sitios de nuestro proyecto. Alguna otra idea?
Siempre va ser mejor modificar un SP que muchos LINQ queries. Pero entonces, en que momento utilizamos los linq querys?. Solo en consultas que tengamos la certeza de que no van a ser modificadas en el tiempo?.
De hecho que tener la lógica de consultas y operaciones de mantenimiento de las tablas en procedimientos almacenados, sera mejor, tienes mas control, y los futuros cambios se harán mas rápidos.
LINQ TO SQL es una forma mas de acceso a datos, es una programación mas sencilla sin tener que lidiar con el Tranct-SQL, en otras palabras te hace la vida mas fácil.
Imaginemos este contexto: Un sistema de ventas, donde se carga en un formulario la lista de precios de los artículos. Los datos que muestra es una código, la descripción de articulo y el precio. Hasta aquí se puede hacer con una consulta LINQ TO SQL y un SP, el tiempo de acceso a los datos es mínima. (En Internet abundan los test sobre rendimiento con Trasact-SQL y SP)
Luego se pide agregar un precio mas a la lista de precios, es decir tener dos precios, quizás una para venta al usuario final y otro para los clientes A1.
Los cambios que tendría que hacer son:
1) Agregar el campo Precio2 a la tabla artículos
2) Modificar la consulta del LINQ TO SQL y también del SP si fuera el caso
3) Modificar mi datagridview donde muestro el resultado de la consulta agregando el campo Precio2
4) Modificar el proceso de asignación de articulo al documento de venta, porque ahora se puede elegir con el precio1 y precio2
Digamos que con esto cuatro cambios soluciono el nuevo requerimiento.
En cualquiera de los dos casos tuve que cambiar la consulta, tanto en el SP y LINQ TO SQL y también cambiar las propiedades del datagridview y ademas el proceso de asignación del articulo a la venta.
De todas formas cambias la base de datos y cambias la aplicación.
Si usamos capas, entonces el cambio se haría en la capa de datos, tanto para el SP o el Transact-SQL.
Saludos... :)
Publicar un comentario en la entrada