É possível
realizar uma consulta LINQ em um DataTable ? A princípio a resposta seria não, porque coleção de linhas do datatable, DataRowCollection, não implementa IEnumerable por isso não podemos realizar consulta LINQ sobre ele. |
Mas se houver uma
maneira de converter nossa coleção de linha de dados (datarow) em
IEnumerable, então o cenário muda e ai poderemos fazer a consulta usando
LINQ.
Neste artigo, vamos mostrar como converter um DataTable em IEnumerable, realizar consultas Linq e finalmente converter o resultado para um DataTable .
Criando o projeto no Visual Studio
Abra o Visual Studio 2013 Express for Windows desktop e crie um novo projeto do tipo Windows Application com o nome Linq_DataTable;
A seguir no formulário padrão Form1.vb inclua o seguintes controles a partir da ToolBox:
1 DataGridView - name = dgvDados
1 Button - name = btnAcessar
1 Label - Text = Selecione a Cidade
1 Combobox = name = cboCidade
Defina o seguinte leiaute no formulário:
Agora vamos incluir uma classe no projeto a partir do menu PROJECT opção Add Class informando o nome AcessoDB.
A seguir vamos definir dois métodos nesta classe conforme o código a seguir:
Imports System.Data.SqlClient
Public Class ConexaoDB
Public Shared Function GetDataTable() As DataTable
Dim conn As New SqlConnection
Dim dataTable As New DataTable("Customers")
Try
conn.ConnectionString = "Data Source=(LocalDB)\v11.0;Initial Catalog=Northwind;Integrated Security=True"
Dim cmd As SqlCommand = conn.CreateCommand()
cmd.CommandText = "Select * from Customers"
cmd.CommandType = CommandType.Text
If conn.State <> ConnectionState.Open Then
conn.Open()
End If
Dim dr As SqlDataReader = cmd.ExecuteReader(CommandBehavior.CloseConnection)
dataTable.Load(dr)
Return dataTable
Catch ex As Exception
MessageBox.Show(ex.Message & " - " & ex.InnerException.ToString)
Return dataTable
Finally
If conn.State = ConnectionState.Open Then
conn.Close()
End If
End Try
End Function
Public Shared Function GetDataTableCidade() As DataTable
Dim conn As New SqlConnection
Dim dataTable As New DataTable("Customers")
Try
conn.ConnectionString = "Data Source=(LocalDB)\v11.0;Initial Catalog=Northwind;Integrated Security=True"
Dim cmd As SqlCommand = conn.CreateCommand()
cmd.CommandText = "Select CustomerId,City from Customers"
cmd.CommandType = CommandType.Text
If conn.State <> ConnectionState.Open Then
conn.Open()
End If
Dim dr As SqlDataReader = cmd.ExecuteReader(CommandBehavior.CloseConnection)
dataTable.Load(dr)
Return dataTable
Catch ex As Exception
MessageBox.Show(ex.Message & " - " & ex.InnerException.ToString)
Return dataTable
Finally
If conn.State = ConnectionState.Open Then
conn.Close()
End If
End Try
End Function
End Class
|
A classe ConexaoDB possui dois métodos que acessam informações da tabela Customers do banco de dados Northwind.mdf do SQL Server.
Por questão de simplicidade eu estou usando a string de conexão no código mas o ideal é obtê-la do arquivo de configuração App.Config.
Os métodos estáticos (Shared) são :
No formulário form1.vb vamos incluir o código abaixo no evento Load para carregar o controle Combobox - cboCidade - com os nomes das cidades :
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim datatable As DataTable = ConexaoDB.GetDataTableCidade
Dim resultado = From dados In datatable.AsEnumerable()
Select dados
With cboCidade
.DisplayMember = "City"
.ValueMember = "CustomerId"
.DataSource = resultado.AsDataView().ToTable()
End With
End Sub
|
Após isso vamos digitar o código abaixo no evento Click do botão de comando para acessar o DataTable e preencher o DataGridView com os dados retornados pela consulta LINQ:
Private Sub btnAcessar_Click(sender As Object, e As EventArgs) Handles btnAcessar.Click
Dim dataTable As DataTable = ConexaoDB.GetDataTable()
Dim resultado = From dados In dataTable.AsEnumerable()
Where dados.Field(Of [String])("City").StartsWith(cboCidade.Text)
Select dados
dgvDados.DataSource = resultado.AsDataView().ToTable()
End Sub
|
Nos dois código definidos estamos usando uma consulta LINQ em um DataTable e nos dois casos usamos o método AsEnumerable() que retorna um objeto IEnumerable<T>, onde o parâmetro genérico T é um DataRow.
Podemos chamar este método como um método de instância em qualquer objeto do tipo DataTable tanto Visual Basic como no C#.
Uma consulta LINQ
funcionam em fonte de dados que implementam a interface
IEnumeragle<T> ou a interface IQueryable.
A classe DataTale não implementa nenhuma dessa interfaces por isso
estamos chamando o método AsEnumerable para usar o DataTable como uma
fonte na cláusula FROM da consulta LINQ.
O objeto enumerable retornado pelo método esta vinculado ao DataTable.
Para retornar os dados para exibição no DataGridView estamos usando o método AsDataView() que cria e retorna um objeto DataView.
Para retornar um
DataTable baseado no DataView usamos o método ToTable() :
resultado.AsDataView().ToTable()
Executando o projeto iremos obter o resultado visto a seguir:
Pegue o projeto aqui: Linq_DataTable.zip
João 6:35 Declarou-lhes Jesus. Eu sou o pão da vida; aquele que vem a mim, de modo algum terá fome, e quem crê em mim jamais terá sede.
João 6:36 Mas como já vos disse, vós me tendes visto, e contudo não credes.
Veja os
Destaques e novidades do SUPER DVD Visual Basic
(sempre atualizado) : clique e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
Quer aprender os conceitos da Programação Orientada a objetos ? Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ? |
Gostou ?
Compartilhe no Facebook
Compartilhe no Twitter
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
http://msdn.microsoft.com/en-us/library/system.data.dataview.totable%28v=vs.110%29.aspx