VB .NET -  Usando LINQ  (revisitado para novatos)


No artigo de hoje eu vou revisitar os conceitos sobre a LINQ mostrando como realizar de forma produtiva consultas LINQ usando a linguagem VB .NET.


Todos os dias, a tecnologia avança e as coisas são feitas mais rapidamente. A LINQ já é um velho conhecido dos que utilizam a plataforma .NET e dispensa apresentações, visto que eu já escrevi dezenas de artigos sobre a LINQ, se desejar mais detalhes veja os artigos nas referências.
 
A Language-Integrated Query (LINQ) adiciona recursos de consulta para o Visual Basic e utiliza uma sintaxe unificada independentemente do tipo de dados. 

Assim, ao invés de enviar uma consulta para um banco de dados ou de trabalhar com diferentes sintaxes para diferentes tipos de dados que estão sendo pesquisados, a LINQ fornece consultas como parte da linguagem VB .NET.

Neste artigo vou fazer uma abordagem bem básica para quem esta iniciando agora mostrando como usar LINQ para realizar consultas em objetos na memória.

Vamos então por a LINQ para trabalhar...

Recursos usados:

Nota: Baixe e use a versão Community 2015 do VS ela é grátis e é equivalente a versão Professional.

Criando o projeto no Visual Studio 2015 Community

Abra o VS 2015 Community e clique em New Project;

Selecione a linguagem Visual Basic e o template Windows Forms Application;

Informe o nome Vbn_LINQ e clique no botão OK;

A seguir inclua no formulário Form1.vb os seguintes controles:

Disponha os controles no formulário segundo o leiaute da figura abaixo:

Definindo as classes Estudante e Curso

Vamos definir as classes Estudante e Curso que serão nosso modelo de domínio.

No menu Project clique em Add Class e informe o nome Estudante e digite o código abaixo:

 Public Class Estudante
    Public Property EstudanteId As Integer
    Public Property EstudanteNome As String
    Public Property CursoId As Integer
    Public Property EstudanteIdade As Integer
End Class

Repita o procedimento e crie a classe Curso com seguinte código:

Public Class Curso
    Public Property CursoId As Integer
    Public Property CursoNome As String
    Public Property CursoDuracao As Integer
End Class

Definindo os métodos GetEstudantes e GetCursos

Agora vamos definir dois métodos no formulário (poderíamos ter criado uma classe) para definir os dados dos estudantes e dos cursos que iremos usar no projeto.

No formulário Form1.vb inclua o método GetEstudantes com o código a seguir:

   Private Function GetEstudantes() As List(Of Estudante)
        Return New List(Of Estudante) From
        {
           New Estudante With {.EstudanteId = 1, .EstudanteNome = "Bianca Lima",
              .CursoId = 3, .EstudanteIdade = 18},
           New Estudante With {.EstudanteId = 2, .EstudanteNome = "Paulo Morgado",
              .CursoId = 1, .EstudanteIdade = 17},
           New Estudante With {.EstudanteId = 3, .EstudanteNome = "Michaela Silva",
              .CursoId = 2, .EstudanteIdade = 16},
           New Estudante With {.EstudanteId = 4, .EstudanteNome = "Maria Ribeiro",
              .CursoId = 1, .EstudanteIdade = 15},
           New Estudante With {.EstudanteId = 5, .EstudanteNome = "José Duarte",
              .CursoId = 2, .EstudanteIdade = 16},
           New Estudante With {.EstudanteId = 6, .EstudanteNome = "Samira Bueno",
              .CursoId = 4, .EstudanteIdade = 16},
           New Estudante With {.EstudanteId = 7, .EstudanteNome = "Sofia Sanches",
              .CursoId = 1, .EstudanteIdade = 15},
           New Estudante With {.EstudanteId = 8, .EstudanteNome = "Humberto Costa",
              .CursoId = 3, .EstudanteIdade = 17},
           New Estudante With {.EstudanteId = 9, .EstudanteNome = "Joana Silveira",
              .CursoId = 4, .EstudanteIdade = 16}
        }
    End Function

Neste método estamos criando uma lista de objetos Estudante que retornará todas os dados dos estudantes.

Repita o procedimento e crie o método GetCursos com seguinte código:

 Private Function GetCursos() As List(Of Curso)
        Return New List(Of Curso) From
           {
              New Curso With {.CursoId = 1, .CursoNome = "Química",
                 .CursoDuracao = 12},
              New Curso With {.CursoId = 2, .CursoNome = "Português",
                 .CursoDuracao = 12},
              New Curso With {.CursoId = 3, .CursoNome = "Biologia",
                 .CursoDuracao = 10},
              New Curso With {.CursoId = 4, .CursoNome = "Fisica",
                 .CursoDuracao = 6}
           }
    End Function

Da mesma forma, esse código retorna uma lista de objetos Curso.

Realizando consultas usando LINQ

Já temos tudo pronto para realizar consultas LINQ em nosso projeto.

1- Retornando informações dos Estudantes - GetEstudantes()

No evento Click do botão - Obter Estudantes - inclua o código a seguir:

 Private Sub btnEstudantes_Click(sender As Object, e As EventArgs) Handles btnEstudantes.Click
        Dim estudantes = GetEstudantes()
        Dim resultadoConsulta = From estudante In estudantes
        lbDados.Items.Clear()
        lbDados.Items.Add("Id" & vbTab & "Nome" & vbTab & vbTab & "Idade" & vbTab & "Curso")
        For Each resultado In resultadoConsulta
            lbDados.Items.Add(resultado.EstudanteId.ToString() & vbTab &
                              resultado.EstudanteNome & vbTab &
                              resultado.EstudanteIdade.ToString() & vbTab &
                              resultado.CursoId.ToString())
        Next
    End Sub

Primeiro obtemos uma lista de objetos Estudante chamando o método GeEstudantes() e a seguir realizando uma consulta LINQ : From estudante In estudantes

Não parece uma declaração da linguagem SQL ??? (Note a cláusula From; Você verá a seguir que as cláusulas Order By, Where , Select , etc também são usadas no LINQ.)

Pois é isso mesmo. A LINQ apresenta uma sintaxe usada nas linguagens funcionais como a SQL de forma tornar mais intuitiva o acesso aos dados.

Perceba também que a lógica da declaração esta invertida em relação a usada na linguagem SQL.

SQL  Select estudante From estudantes
LINQ  From estudante in estudantes

Um dos motivos desta inversão de ordens é  o uso recurso IntelliSense, pois quando você indica primeiro a origem dos dados ele pode mostrar as listas de membros de tipos nos objetos em sua coleção. Outro motivo , segundo Anders Hejlsberg , seria que esta ordem esta mais próxima da nossa lógica de pensamento. Quando você digita uma instrução SQL iniciando com Select na verdade você já esta pensando na origem dos dados , condições , agrupamentos. etc.

A cláusula From é a mais importante do LINQ To SQL pois é usada em todas as consultas. Uma consulta deve sempre começar com From. (O Select pode estar implícito o From não.)

Depois basta acessar o resultado da consulta e exibir as informações dos objetos Estudante.

2- Retornando informações dos Cursos - GetCursos()

No evento Click do botão - Obter Cursos - inclua o código a seguir:

 Private Sub btnCursos_Click(sender As Object, e As EventArgs) Handles btnCursos.Click
        Dim cursos = GetCursos()
        Dim resultadoConsulta = From cur In cursos
        lbDados.Items.Clear()
        lbDados.Items.Add("Id" & vbTab & "Nome" & vbTab & vbTab & "Curso")
        For Each resultado In resultadoConsulta
            lbDados.Items.Add(
                resultado.CursoId.ToString() & vbTab &
                resultado.CursoNome & vbTab & vbTab &
                resultado.CursoDuracao.ToString()
                )
        Next
    End Sub

Neste código estamos realizando a consulta LINQ para obter uma lista de objetos Curso chamando o método GetCursos().

Depois fazemos uma consulta LINQ -  From cur In cursos - e exibimos o resultado no ListBox.

3- Filtrando os Estudantes por Curso

No evento Click do botão - Filtrar Alunos por Curso - inclua o código a seguir:

  Private Sub btnFiltrarAlunosPorCurso_Click(sender As Object, e As EventArgs) Handles btnFiltrarAlunosPorCurso.Click
        Dim estudantes = GetEstudantes()
        Dim msg, titulo, valor As String
        Dim objValor As Object
        msg = "Informe o Id do Curso "
        titulo = "Filtrar por Curso" ' define o titulo.
        valor = "1"            ' define o valor padrao
        ' Exibe mensagem posicionada 
        objValor = InputBox(msg, titulo, valor, 800, 400)
        If (String.IsNullOrEmpty(objValor)) Then
            MessageBox.Show("Operação Cancelada..", "Cancelada")
            Return
        Else
            Dim resultadoConsulta = From estudante In estudantes
                                                    Where estudante.CursoId = objValor.ToString
            lbDados.Items.Clear()
            lbDados.Items.Add("Id" & vbTab & "Nome" & vbTab & vbTab & "Idade" & vbTab & "Curso")
            For Each resultado In resultadoConsulta
                lbDados.Items.Add(resultado.EstudanteId.ToString() & vbTab &
                                             resultado.EstudanteNome & vbTab &
                                             resultado.EstudanteIdade.ToString() & vbTab &
                                             resultado.CursoId.ToString())
            Next
        End If
    End Sub

Neste código estamos usando a função InputBox para que o usuário informe o Id do curso que será armazenado na variável objValor e depois usada na consulta LINQ.

A consulta LINQ seleciona todos os alunos cujo Id do Curso seja igual ao informado:

Dim resultadoConsulta = From estudante In estudantes
                                        Where estudante.CursoId =
objValor.ToString

Perceba que não estamos usando a cláusula SELECT.

Executando o projeto iremos obter:

4- Filtrando os Cursos

No evento Click do botão - Filtrar Cursos - inclua o código a seguir:

 Private Sub btnFiltrarCursos_Click(sender As Object, e As EventArgs) Handles btnFiltrarCursos.Click
        Dim cursos = GetCursos()
        Dim msg, titulo, valor As String
        Dim objValor As Object
        msg = "Informe o Id do Curso "
        titulo = "Filtrar por Curso"   ' define o titulo.
        valor = "1"                          ' define o valor padrao
        ' Exibe mensagem posicionada 
        objValor = InputBox(msg, titulo, valor, 800, 400)
        If (String.IsNullOrEmpty(objValor)) Then
            MessageBox.Show("Operação Cancelada..", "Cancelada")
            Return
        Else
            Dim resultadoConsulta = From curso In cursos
                                    Where curso.CursoId = objValor
                                    Select curso.CursoNome, curso.CursoDuracao
            lbDados.Items.Clear()
            lbDados.Items.Add("Nome" & vbTab & vbTab & "Duraçao")
            For Each resultado In resultadoConsulta
                lbDados.Items.Add(
                    resultado.CursoNome & vbTab & vbTab &
                    resultado.CursoDuracao.ToString()
                    )
            Next
        End If
    End Sub

Neste código estamos usando a função InputBox para que o usuário informe o Id do curso que será armazenado na variável objValor e depois usada na consulta LINQ.

A consulta LINQ seleciona todos os cursos cujo Id do Curso seja igual ao informado.

Observe que agora estamos usando a instrução SELECT para selecionar o nome do curso e a sua duração apenas.

5- Resultando uma combinação de informações de Estudantes e Cursos

No evento Click do botão - Combinar Dados - inclua o código a seguir:

    Private Sub btnCombinarDados_Click(sender As Object, e As EventArgs) Handles btnCombinarDados.Click
        Dim estudantes = GetEstudantes()
        Dim cursos = GetCursos()
        Dim resultadoConsulta = From stu In estudantes, cur In cursos
                                               Where stu.CursoId = cur.CursoId
                                               Select stu, cur
                                               Order By stu.EstudanteNome
        lbDados.Items.Add("Aluno" & vbTab & vbTab & vbTab & "Curso")
        For Each resultado In resultadoConsulta
            lbDados.Items.Add(
                resultado.stu.EstudanteNome & vbTab & vbTab &
                resultado.cur.CursoNome.ToString()
                )
        Next
    End Sub

Neste código obtemos uma lista de objetos Estudante e uma lista de objetos Curso em memória e a seguir criamos uma consulta LINQ.

Nesta consulta combinamos as informações de estudantes e cursos com base no Id do Curso onde estamos usando a cláusula SELECT para selecionar todos os estudantes com seu respectivo curso, e usando a cláusula ORDER BY para ordernar pelo nome do estudante:

 Dim resultadoConsulta = From stu In estudantes, cur In cursos
                                         Where stu.CursoId = cur.CursoId
                                         Select stu, cur
                                         Order By stu.EstudanteNome

Veja o resultado obtido a seguir:

Assim, revimos os conceitos básicos do LINQ e realizamos consultas para obter informações de objetos em memória de uma forma bem simples usando as cláusulas From, Where, Select e Order by.

Pegue o projeto completo aqui :   Vbn_LINQ.zip

(Disse Jesus) "Quem ama a sua vida perdê-la-á, e quem neste mundo odeia a sua vida, guardá-la-á para a vida eterna."
João 12:25

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 ?

Quer aprender a criar aplicações Web Dinâmicas usando a ASP .NET MVC 5 ?

  Gostou ?   Compartilhe no Facebook   Compartilhe no Twitter

Referências:


José Carlos Macoratti