VB 2008 - Usando LINQ To SQL


Eu já abordei o LINQ em dois artigos:

E há ainda muito o que falar sobre cada uma das características e funcionalidades deste fantástico recurso disponível no .NET Framework 3.5 e que você pode usar no Visual Basic 2008.

Este artigo vai mostrar como usar o LINQ To SQL no VB 2008 Express para realizar tarefas de consulta atualização e exclusão de dados. Portanto você deve ter o VB 2008 Express instalado e o SQL Server Express.

Abra o VB 2008 Express e crie um novo projeto no menu FIle->New Project do tipo Windows Forms Application com o nome usandoLINQToSQL;

A seguir no menu Project opção Add New Item selecione na janela Templates o template LINQ to SQL Classes alterando o nome para Northwind.dbml pois iremos efetuar a conexão com o banco de dados Northwind.mdf (você pode usar qualquer nome);

No menu View e selecione DataBase Explorer e clique com o botão direito do  mouse sobre o item Data Connections e selecione Add Connection...

Na janela Add Connection Clique no botão Browse e selecione o banco de dados Northwind.mdf a partir do local onde você o instalou e clique no botão Abrir;

Neste momento será exibida a janela do descritor Objeto Relacional. Expanda os objetos do banco de dados Northwind.mdf e selecione a tabela Customers arrastando e soltando na janela Object Relational Designer;

A tabela Customers do banco de dados será mapeada como uma classe (campos como propriedades, procedures e funções como métodos)  e você terá no Descritor a classe que representa os objetos do banco de dados; Cada propriedade definida no objeto Customer esta mapeada para cada coluna da tabela Customers.

O arquivo Northwind.dbml contém o arquivo XML com informações sobre o leiaute das tabelas que foram mapeadas e também o descritor contendo as classes geradas pelo mapeamento. Após encerrar o mapeamento você já terá acesso aos recursos do LINQ To SQL com direito a intellisense completo das informações referente as tabelas mesmo sem conhecer nada sobre elas.

Se você observar as propriedades do DataContext gerado irá perceber que o nome dado ao contexto é NorthwindDataContext e verá também a conexão com o banco de dados Northwind.mdf

O Banco de dados é mapeado em um objeto DataContext permitindo acesso a tabelas de forma transparente sem termos que nos preocupar com conexão. Teremos que apenas usar os recursos do LINQ To SQL.

O DataContext é o responsável por gerar as instruções SQL da sua linguagem de consulta e então mapear as linhas de dados retornadas a partir do seu banco de dados para objetos.

Vamos agora efetuar a vinculação dos objetos com os dados e a interface; no menu Data selecione Add New Data Source e na janela do assistente selecione a opção Object clicando no botão Next>

A seguir selecione o objeto Customer criado anteriormente e clique no botão Next> e a seguir em Finish;

A partir da janela Data Sources (para visualizar selecione Show Data Sources no menu Data) você verá os objetos referente a tabela Customers. Selecione e arraste o objeto Customer para o formulário form1.vb;

Se você abrir neste momento o formulário form1.vb verá que temos que digitar o código para carregar os dados no DataGridView gerado usando uma consulta LINQ . Digite o código abaixo no evento Load do formulário:

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

db.Log = Console.Out 'gera os eventos na janela de console do debug

Dim Clientes = From cli In db.Customers _
                        Order By cli.CustomerID _
                        Select cli.CustomerID, cli.CompanyName, cli.ContactName, cli.Country


Me.CustomerBindingSource.DataSource = Clientes

End Sub

Executando o projeto iremos obter:

Acima vemos o log sendo exibido na janela Output devido a linha de código db.Log = Console.Out onde vemos a consulta SQL gerada pelo DataContext.

Note que no código não definimos string de conexão nem objetos para efetuar a conexão pois já foi tudo definido no DataContext.

A linha de código :

Dim Clientes = From cli In db.Customers _
                      Order By cli.CustomerID _
                      Select cli.CustomerID, cli.CompanyName, cli.ContactName, cli.Country

Seleciona os clientes da tabela Customers por ordem de código.

A linha de código - Me.CustomerBindingSource.DataSource = Clientes- vincula os dados obtidos ao objeto BindingSource gerado exibindo os dados no DataGridView que tem a sua propriedade DataSource definida para o CustomerBindingSource.

A seguir selecione o icone Save do componente BindingNavigator e na janela de propriedades habilite o controle definindo Enabled=true e clique duas vezes sobre o ícone para abrir o evento Click deste botão;

A seguir inclua o código abaixo no evento Click para poder salvar as alterações feitas no DataGridView:

Private Sub CustomerBindingNavigatorSaveItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CustomerBindingNavigatorSaveItem.Click

Me.Validate()
Me.CustomerBindingSource.EndEdit()

Try
 
 db.SubmitChanges()
   MsgBox("Operação salva com sucesso.")
Catch ex As Exception
   MsgBox(ex.Message)
End Try

End Sub

Executando o projeto e incluindo um novo Cliente no DataGridView iremos obter:

Ao clicar no botão Save vemos que o cliente é incluído e observando o log vemos a instrução SQL INSERT INTO gerada pelo LINQ.

Notou a linha de código db.SubmitChanges() ?

Quando SubmitChanges() é invocado o LINQ To SQL automaticamente gera e executa comandos SQL a fim de transmitir as alterações de volta ao banco de dados. Você pode no entanto sobrescrever este comportamento chamando uma stored procedure.

A seguir vou alterar a coluna ContactTitle de Manager para President e clicar no botão Save. O resultado pode ser visto abaixo:

Novamente observe a instrução SQL UPDATE gerada pelo LINQ para atualizar a coluna.

Vamos agora incluir um TextBox e um Button no controle BindingNavigator e criar uma rotina para filtrar os dados da tabela Customers. Altere a propriedade Name do Button para btnProcurar e a propriedade Name do TextBox para txtBusca.

A seguir clique com o botão direito sobre o Button incluído e selecione a opção Set image e defina uma imagem usando um ícone sugestivo para busca através da janela Select Resource na opção Import ou use um recurso do projeto em Project resource file.

Remova ou comente o código usado no evento Load pois não vamos mais carregar os dados da tabela quando da carga do formulário. Agora vamos apresentar o formulário vazio e selecionar os clientes conforme o critério informado pelo usuário na caixa de texto txtBusca.

Clique duas vezes sobre o Button incluído e digite o código abaixo no evento Click:

Private Sub btnProcurar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnProcurar.Click

Dim consulta = From cliente In db.Customers _
                       Where cliente.CustomerID Like Me.txtBusca.Text & "*" _
                       Select cliente

Me.CustomerBindingSource.DataSource = consulta

End Sub

executando o projeto e informando a letra A como critério iremos obter:

Se incluirmos novamente a linha de código db.Log = Console.Out na consulta e observarmos iremos nota a instrução da consulta SQL usando a cláusula LIKE gerada pelo LINQ agora usando a letra B.

Para encerrar vamos definir o código LINQ para excluir registros. Clique duas vezes sobre o ícone de exclusão e no evento Click inclua o seguinte código:

If CustomerDataGridView.SelectedRows.Count > 0 Then

Try
  Dim cliente1 = (From cliente In db.Customers _
                         Where cliente.CustomerID = criterio _
                         Select cliente).Single


  db.Customers.DeleteOnSubmit(cliente1)
  db.SubmitChanges()

Catch ex As Exception
    MessageBox.Show(Me, ("ocorreu o seguinte erro ao deletar o registro :" + ex.Message), "Erro")
End Try

Defina no início do formulário a variável criterio como do tipo String e para obter o valor do código do cliente vamos usar o evento CellEnter do DataGridView conforme código abaixo:

Private Sub CustomerDataGridView_CellEnter(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles CustomerDataGridView.CellEnter
    '---Quando o usuário clicar no controle , exibe o conteudo da célula
  
 criterio = CustomerDataGridView.Rows(e.RowIndex).Cells(0).Value

End Sub

O código acima obtém o valor da primeira célula do DataGridView que refere-se ao código do cliente e atribui a variável criterio.

A instrução LINQ :

Dim cliente1 = (From cliente In db.Customers _
                       Where cliente.CustomerID = criterio _
                       Select cliente).Single

Seleciona um único cliente (garantida feita pela cláusula Single) com o código selecionado no DataGridView.

Executando o projeto , efetuando uma seleção de clientes por criterio e em seguida excluindo o registro iremos obter:

Acima vemos a instrução SQL DELETE FROM gerada pelo LINQ.

Nota: Você pode obter um erro durante a operação de exclusão se houver relacionamentos entre as tabelas. No caso a tabela Customers esta relacionada com a tabela Orders, e, neste caso a integridade referencial não permitirá a exclusão do registro.

Como vimos o LINQ To SQL permite efetuar as operações de consulta, atualização e exclusão em uma fonte de dados de uma forma simples e usando pouco código.

Pegue o projeto completo aqui: usandoLINQToSQL.zip

Aguarde em breve mais artigos sobre LINQ ...


José Carlos Macoratti