VB .NET - Usando uma consulta LINQ em um DataTable

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

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 :

  1. GetDataTable - Acessa a tabela Customers e retorna todos os registros da tabela em um DataTable
  2. GetDataTableCidade - Acessa a tabela Customers e retorna os campos CustomerId e City em um DataTable

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:


José Carlos Macoratti