VB .NET - Usando o LINQ to SQL em Camadas
Neste artigo eu vou mostrar um exemplo básico de como usar o LINQ To SQL em uma aplicação em camadas. O objetivo é dar uma introdução ao assunto e mostrar uma das possibilidades de como usar os recursos do LINQ To SQL em uma aplicação Windows Forms que usa uma arquitetura em camadas.
Não serão considerados muitos aspectos que podem ocorrer em aplicações distribuídas ou que envolvam um cenário mais complexo por este motivo você deve considerar o artigo apresentado como o ponto de partida para os seus estudos e não como uma solução visto que não estamos abordando questões como concorrência, transações, compartilhamento, etc.
Obs: Você deve considerar a possibilidade de utilização do Entity Framework em substituição ao LINQ to SQL.
Os recursos necessários para acompanhar o exemplo deste artigo são:
Visual Studio 2008 com service Pack1;
Banco de dados SQL Server 2005 ou 2008;
As etapas envolvidas na criação do projeto são:
Criar o banco de dados Cadastro no SQL Server;
Criar a tabela Produtos com os campos : id (int, PK) , nome (nvarchar(50), preco (money);
Criar a stored procedure selecionaProdutoPorID conforme abaixo;
ALTER PROCEDURE
selecionaProdutoPorID@id
intAS
Select
* from Produtos Where id = @idreturn
Criar a solução LinqEmCamadas;
Criar os seguintes projetos na solução :
BLL - projeto do tipo Class Library da camada de negócios - definição da classe produtoBLL;
DAL - projeto do tipo Class Library da camada de acesso aos dados - definição da classe produtoDAL;
Entities - projeto do tipo Class Library das entidades mapeadas geradas pelo LINQ to SQL - definição do arquivo de mapeamento Cadastro.dbml;
UI - projeto do tipos Windows Application da interface com o usuário ou aplicação Windows Forms- definição do formulário frmCadastro.vb;
- O projeto BLL deverá possuir uma
referência ao projeto DAL e ao projeto Entities;
- O projeto DAL deverá possuir uma referência ao projeto Entities;
- O projeto UI deverá possui uma referência ao projeto BLL e ao projeto Entities;
Na figura abaixo temos um esquema bem simplificado da arquitetura da nossa aplicação mostrando as referências e a hierarquia de chamadas:
A seguir vemos a uma figura 1.0 mostrando a estrutura do banco de dados(tabelas e sotred procedure), da solução (4 projetos) e do leiaute do formulário :
Figura 1.0 - estrutura da solução exibindo os 4 projetos, o leiaute do formulário e a estrutura do banco de dados Cadastro.mdf |
Abaixo temos o código do formulário onde a cada evento Click de cada controle Button associamos o código pertinente:
Imports BLL Public Class frmCadastro Dim bll As BLL.Macoratti.ProdutoBLL Private Sub btnExibir_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExibir.Click bll = New BLL.Macoratti.ProdutoBLL dgvProdutos.DataSource = bll.exibeProdutos End Sub Private Sub btnNovo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnNovo.Click bll = New BLL.Macoratti.ProdutoBLL Dim p As New Entities.Produto p.nome = txtNome.Text p.preco = txtPreco.Text bll.novoProduto(p) End Sub Private Sub btnAtualizar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAtualizar.Click bll = New BLL.Macoratti.ProdutoBLL Dim p As New Entities.Produto p.id = txtID.Text p.nome = txtNome.Text p.preco = txtPreco.Text bll.alteraProduto(p) End Sub Private Sub btnExcluir_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExcluir.Click bll = New BLL.Macoratti.ProdutoBLL Dim p As New Entities.Produto p.id = txtID.Text bll.removeProduto(p) End Sub Private Sub btnProcurar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnProcurar.Click bll = New BLL.Macoratti.ProdutoBLL Dim p As New List(Of Entities.Produto) Dim codigo As Integer = CInt(txtID.Text) p = bll.procuraProduto(codigo) txtNome.Text = p(0).nome txtPreco.Text = p(0).preco End Sub End Class |
Em cada evento criamos uma instância da classe ProdutoBLL e acionamos o método correspondente à tarefa a ser realizada na camada de negócios - BLL passando como parâmetro a entidade Produto, dessa forma temos:
botão Novo : bll.novoProduto(p)
botão Excluir : bll.alteraProduto(p)
botão Atualizar : bll.removeProduto(p)
botão Exibir : bll.exibeProdutos
Na figura 2.0 temos o descritor LINQ to SQL exibindo a entidade Produto gerada pelo mapeamento OR/M e o método selecionaProdutoPorID gerado a partir da stored procedure;
Figura 2.0 - Descritor LINQ to SQL exibindo a entidade Produto e o método gerado a partir da stored procedure |
No arquivo app.Config temos a string de conexão gerada e usada para conexão com o banco de dados:
<? xml version="1.0" encoding="utf-8" ?>< configuration>< configSections></ configSections>< connectionStrings>< add name="Entities.My.MySettings.CadastroConnectionString" connectionString="Data Source=MAC\SQLEXPRESS;Initial Catalog=Cadastro;Integrated Security=True"providerName="System.Data.SqlClient" /> </ connectionStrings>...........
|
Na figura 3.0 temos a definição da classe ProdutoDAL que é responsável pela camada de acesso a dados. Observe a referência ao projeto Entities;
Figura 3.0 - Classe ProdutoDAL da camada de acesso a dados DAL |
Na figura 4.0 temos a definição da classe ProdutoBLL responsável pelas regras de negócio. Observe que temos uma referência a classe ProdutoDAL e que estamos usando a entidade Produto nos métodos da classe;
Figura 4.0 - Classe ProdutoBLL da camada de negócios BLL |
Cada método definido na camada de negócios(BLL) chama o método correspondente na camada de acesso a dados(DAL) e passando o parâmetro Entities.Produto ou o codigo do produto.
Executando a solução veremos que todas as operações CRUD implementadas funcionam sem problema:
Acabamos de ver como é simples usar os recursos do LINQ to SQL em seus projetos em camadas usando o mapeamento OR/M e stored procedures, reiterando o que disse no início do artigo, que estamos usando um cenário muito simples com uma tabela apenas e que também não me preocupei em fazer o tratamento dos erros, quesito indispensável em qualquer aplicação.
Fica então como exercício a implementação do tratamento de erros(Try/Catch/Finally) e. para um cenário mais complexo os ajustes necessários no tratamento do contexto.
Pegue o projeto completo : LinqEmCamadas.zip
Eu sei é apenas LINQ to SQL , mas eu gosto...
A vídeo-aula deste artigo esta no Super DVD Vídeo Aulas.
Referências:
José Carlos Macoratti