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:

As etapas envolvidas na criação do projeto são:

ALTER PROCEDURE selecionaProdutoPorID

@id int

AS

Select * from Produtos Where id = @id

return

- 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:

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