VB.NET -  LINQ to SQL : Criando Entidades e mapeamento OR/M


E mais uma vez cá estou eu a falar sobre LINQ, mais precisamente sobre LINQ to SQL com VB .NET. Neste artigo vou mostrar como criar uma aplicação Windows Forms onde vamos criar as entidades e efetuar o mapeamento para a tabela Customers do banco de dados Northwind.mdf sem usar o descritor Visual do LINQ to SQL, em seguida vamos acessar os dados da tabela usando uma consulta LINQ.

Como exemplo eu vou usar a tabela Customer do banco de dados Northwindo.mdf . Essa tabela possui a estrutura mostrada na figura 1.0:

Você deve possuir o SQL Server 2005 Express Instalado e o banco de dados Northwind.mdf.

Você pode fazer o download do SQL Server 2005 Express aqui.

Faça o download do banco de dados Northwind.mdf  aqui.

Obs: O SQL Server Management Studio é uma ferramenta gratuita que você pode usar para gerenciar o seu SQL Server 2005 Express.

Pegue o SQL Server Management Studio aqui.

Figura 1.0 - Tabela Customer  

Iremos seguir as seguintes etapas no desenvolvimento desta aplicação:

  1. Criar uma classe de entidade para a tabela Customers;
  2. Criar um data context fortemente tipado para expor as tabelas relacionadas;
  3. Criar um formulário Windows onde iremos usar os recursos do LINQ to SQL para preencher um combobox com as cidades da tabela Customers e preencher um DataGridView com base na seleção da cidade feita pelo usuário;

Para poder usar os recursos do LINQ to SQL e ter acesso as classes que vão permitir a interação com o banco de dados temos que fazer referência ao assembly LINQ através dos seguintes namespaces:

Para referenciar os namespaces clique com o botão direito do mouse sobre o nome do projeto e selecione Add Reference e na guia .NET selecione o componente System.Data.Linq e clique em OK;

Já temos tudo pronto para poder a criar a nossa aplicação e vamos usar o Visual Basic 2008 Express Edition e criar um novo projeto Windows Forms Application usando a linguagem Visual Basic com o nome linqvb1;

Será exibida na janela Solution Explorer os arquivos : Form1.vb.

1-) Criando a classe de entidade para a tabela Clientes

Nesta etapa vamos criar a classe de entidade para a tabela Customers que deve representar a tabela Customers em uma classe .NET; é desta forma que o LINQ To SQL efetua a modelagem com ajuda de certos atributos.

Clique com o botão direito do mouse sobre o nome do projeto e selecione a opção Add New Item;

Na janela selecione o template Class e informe o nome Customers.vb;

A seguir inclua o seguinte código no arquivo :

Imports System.Data.Linq.Mapping

<Table(Name:="Customers")> Public Class Customer

    <Column(IsPrimarykey:=True)> Public customerid As String

 

Private _city As String

 

<Column(Storage:="_city")> _

Public Property city() As String

Get

   Return _city

End Get

Set(ByVal value As String)

  _city = value

End Set

End Property

 

Private _contactName As String

 

<Column(Storage:="_contactName")> _

Public Property contactName() As String

Get

    Return _contactName

End Get

Set(ByVal value As String)

   _contactName = value

End Set

End Property

Private _phone As String

 

<Column(Storage:="_phone")> _

Public Property phone() As String

Get

   Return _phone

End Get

Set(ByVal value As String)

   _phone = value

End Set

End Property

End Class

O atributo <Table> possui a propriedade Name que podemos usar para especificar o nome exato da tabela do banco de dados. Se a propriedade Name não for informada o LINQ To SQL  irá assumir que a tabela do banco de dados possui o mesmo nome da classe.

No nosso exemplo a classe Customer consiste de 3 propriedades publicas : customerid, contactName e Phone. O que torna esta classe especial são os atributos <Table> e <Column>.

O atributo <Table> na classe Customer indica que a classe representa uma tabela de um SGBD.

A propriedade Name do atributo <Table> especifica o nome da tabela no banco de dados. Se a classe e tabela tiverem o mesmo nome você não precisa definir a propriedade Name.

Somente as instâncias das classes declaradas como tabelas serão armazenadas no banco de dados. Instâncias desses tipos de classes são conhecidas como entidades e as classes como classes de entidades.

Para associar a classe com a tabela precisamos definir cada campo ou propriedade que desejamos associar com a coluna do banco de dados e para isso usamos o atributo Column.

A atributo <Column> especifica que a propriedade relacionada é uma coluna de uma tabela. Este atributo possui diversas propriedades, a seguir temos as mais importantes:

No nosso exemplo custeomerid é marcada com a propriedades IsPrimaryKey indicando que representa uma chave primária. 

2-) Criando um data context fortemente tipado para expor as tabelas relacionadas

No LINQ to SQL temos o conceito de Data Context que é quem efetua a comunicação coma fonte de dados. Um Data Context é uma classe que deriva da classe base DataContext.

Com o objetivo de criar um data context fortemente tipado precisamos criar uma classe que derive da classe base DataContext.

Clique com o botão direito do mouse sobre o nome do projeto e selecione a opção Add New Item;

Na janela selecione o template Class e informe o nome Northwind.vb;

A seguir inclua o seguinte código no arquivo :

Imports System.Data.Linq

 

Public Class Northwind

        Inherits DataContext

 

Public Sub New(ByVal connectionString As String)

          MyBase.New(connectionString)

End Sub

 

Public Clientes As Table(Of Customer)

 

End Class

A classe Northwind herda da classe base DataContext e precisa fornecer um construtor com um parâmetro. No nosso exemplo o construtor aceita uma string de conexão com o banco de dados e a passa para a classe base.

A seguir temos a definição de uma tabela de objetos Customer que é a forma usada para expor os objetos previamente mapeados pelo LINQ to SQL com o mundo externo.

Agora estamos pronto para usar as classes a partir do formulário windows.

Você pode estar intrigado por não estar vendo até o momento a definição dos objetos para realizar a conexão com o banco de dados mas isso será feito pelo datacontext

3- ) Criando um formulário Windows para usar os recursos do LINQ to SQL

Agora vamos usar o formulário windows  form1.vb criado por padrão conforme e definir os componentes conforme o leiaute a seguir:

A partir da ToolBox inclua os componentes : Label , ComboBox (Name=cboCidade), DataGridView (Name=gdvDados) e Button (Name=btnExibir)

Defina o seguinte namespace no formulário:

Imports System.Data.Linq

Declare a seguinte variável para tornar a string de conexão visível:

Dim conn As String = "Data Source=MAC\SQLEXPRESS;Initial Catalog=Northwind;Integrated Security=True;User ID='Macoratti';Password=''"

No evento Load do formulário form1.vb inclua o código a seguir:

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


'instancia um datacontext passando a string de conexão para o construtor

Dim db = New Northwind(conn)

 

'seleciona  as cidades da tabela Customers

Dim cli = From c In db.Clientes _

             Select c.city Distinct _

                  Order By city


'exibe as cidades selecionadas no combobox

cboCidade.DataSource = cli.ToList

End Sub

Agora no evento Click do botão btnExibir digite o código abaixo:

Private Sub btnExibir_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExibir.Click

 

'instancia um datacontext passando a string de conexão para o construtor

Dim db = New Northwind(conn)

 

'define o critério de seleção pelo valor selecionado na combobox

Dim crit As String = cboCidade.SelectedValue

 

'filtra os dados da tabela customers pelo critério definido pela combo selecionada

Dim cli = From c In db.clientes _

                   Where (c.city = crit) Select c

 

'exibe no datagridview os dados da tabela customers

gdvDados.DataSource = cli.ToList

End Sub

Executando o projeto, primeiro vemos que a combobox exibe as cidades obtidas a partir da tabela Customers. Ao selecionar uma cidade e clicar no botão Exibir dados tabela Customers , vemos a exibição da informação filtrada pela cidade selecionada;

Percebeu que a quantidade de código necessária para realizar as tarefas básica diminuiu muito ??? E notou que não precisamos nos preocupar com dataSet, dataReader, dataAdapter, abrir conexão, fechar conexão, etc.

Eu sei é apenas LINQ to SQL mas eu gosto...

Até o próximo artigo ASP .NET 


José Carlos Macoratti