LINQ-  Populando uma coleção de objetos a partir de diversas fontes (VB. NET)

 

 Neste artigo eu vou mostrar como podemos popular uma coleção de objetos a partir de múltiplas fontes em uma aplicação Windows Forms usando a linguagem VB .NET.

Neste artigo vamos recordar como usar os recursos da LINQ para mesclar dados de diferentes fontes em uma sequência onde teremos a criação de novos tipos.

O cenário é o seguinte :

Temos dois arquivos texto no formato CSV, onde o delimitador é a vírgula, onde estão armazenados os dados dos alunos e suas notas.

Assim, o arquivo alunos.csv possui os seguintes dados:

Macoratti,45,111
Cristina,25,112
Marcia,19,113
Ricardo,22,114
Paulo,23,115
Francisca,27,116
Maria,19,117
Bianca,20,118
Jessica,22,119
Amanda,21,120
Pedro,19,121
Samuel,23,122
alunos.csv

Temos ai representados o nome, a idade e o código do aluno.

Temos também o arquivo notas.csv que possui os seguintes dados:

111, 97, 92, 81, 60
112, 75, 84, 91, 39
113, 88, 94, 65, 91
114, 97, 89, 85, 82
115, 35, 72, 91, 70
116, 99, 86, 90, 94
117, 93, 92, 80, 87
118, 92, 90, 83, 78
119, 68, 79, 88, 92
120, 99, 82, 81, 79
121, 96, 85, 91, 60
122, 94, 92, 91, 91
notas.csv

Aqui os dados representam o código do aluno e as 4 notas dos exames bimestrais.

Nosso objetivo é ler o conteúdo desses arquivos e realizar uma consulta LINQ que mescle essas informações e exiba em um formulário Windows Forms os dados dos alunos e a média das suas notasa.

Criando o projeto no Visual Studio Community

Vamos criar uma solução usando o Visual Studio Community 2015 do tipo Windows Forms Application usando a linguagem C# com o nome Vbnet_Juntando_Arquivos.

Acionando o menu Project -> Add Class vamos criar uma classe chamada Aluno que vai representar os dados dos alunos e suas notas : Nome, Idade, ID e NotasExames

Public Class Aluno
    Public Nome As String
    Public Idade As Integer
    Public ID As Integer
    Public NotasExames As List(Of Integer)
End Class

No formulário form1.vb da solução criada vamos usar 3 Panels , 4 ListBox e 3 Buttons a partir da ToolBox e criar o seguinte leiaute:

Agora vamos implementar o código no formulário:

Declare no início do formulário as seguintes variáveis que são arrays de strings onde iremos armazenar os dados lidos dos arquivos .csv :

Dim nomes() As String
Dim notas() As String

1- Botão - Ler Notas - Código que lê o arquivo notas.csv e exibe no listbox

Private Sub btnLerNotas_Click(sender As Object, e As EventArgs) Handles btnLerNotas.Click

        Dim origem As String = "c:\dados\notas.csv"

        If File.Exists(origem) Then
            notas = File.ReadAllLines(origem)
            lbNotas.Items.AddRange(notas)
            btnLerNomes.Enabled = True
        Else
            MessageBox.Show("O arquivo não existe.", "Não Existe")
        End If
    End Sub

 

2- Botão - Ler Nomes - Código que lê o arquivo aslunos.csv e exibe no listbox

Private Sub btnLerNomes_Click(sender As Object, e As EventArgs) Handles btnLerNomes.Click

        Dim origem As String = "c:\dados\alunos.csv"

        If File.Exists(origem) Then
            nomes = File.ReadAllLines(origem)
            lbNomes.Items.AddRange(nomes)
            btnJuntaDados.Enabled = True
        Else
            MessageBox.Show("O arquivo não existe.", "Não Existe")
        End If

    End Sub

 

3- Botão - Juntar Dados via LINQ - Código onde realizamos duas consultas LINQ :

  1. A primeira consulta retorna os dados do alunos e as notas dos exames a partir da qual calculamos a média das notas para cada aluno;

  2. A segunda retorna todos os dados dos alunos para exibirmos no listbox;

 Private Sub btnJuntaDados_Click(sender As Object, e As EventArgs) Handles btnJuntaDados.Click

        Try
            Dim consultaNomesNotas = From nomeLinha In nomes
                                                       Let dadosAluno = nomeLinha.Split(New Char() {","})
                                                       From notaLinha In notas
                                                       Let notaAluno = notaLinha.Split(New Char() {","})
                                                       Where dadosAluno(2) = notaAluno(0)
                                                       Select New Aluno() With {
                                                                            .Nome = dadosAluno(0), .Idade = dadosAluno(1), .ID = dadosAluno(2),
                                                                            .NotasExames = (From notaTexto In notaAluno Skip 1
                                                                             Select Convert.ToInt32(notaTexto)).ToList()}

            Dim consultaAlunos = From name In nomes
                                              Let n = name.Split(New Char() {","})
                                              From id In notas
                                              Let n2 = id.Split(New Char() {","})
                                              Where n(2) = n2(0)
                                              Select n2(0) & "," & n(0) & "," & n(1) & " Notas : " & n2(1) & "," &
                                                       n2(2) & "," & n2(3) & "," & n2(4)


            ExibeResultado(consultaAlunos)

            ' Armazena o resultado da consulta para um acesso mais rápido
            Dim alunos As List(Of Aluno) = consultaNomesNotas.ToList()
            For Each a In alunos
                lbMedias.Items.Add("A média das notas de " & a.Nome & " é " & a.NotasExames.Average())
            Next
        Catch ex As Exception
            MessageBox.Show("Erro : " + ex.Message)
        End Try

    End Sub

 

O código é bem simples e eu vou me ater somente às duas consultas:

Dim consultaNomesNotas = From nomeLinha In nomes
                                            Let dadosAluno = nomeLinha.Split(New Char() {","})
                                            From notaLinha In notas
                                            Let notaAluno = notaLinha.Split(New Char() {","})
                                            Where dadosAluno(2) = notaAluno(0)
                                            Select New Aluno() With {
                                                                            .Nome = dadosAluno(0), .Idade = dadosAluno(1), .ID = dadosAluno(2),
                                                                            .NotasExames = (From notaTexto In notaAluno Skip 1
                                                                                                      Select Convert.ToInt32(notaTexto)).ToList()}


- A consulta a seguir mescla o conteúdo de dois arquivos distintos com base em valores comuns de ID.
- Usamos várias cláusulas From ao invés de uma cláusula de JOIN para armazenar os resultados de notaLinha.Split.
- Observe a criação dinâmica de uma lista de inteiros para o membro NotasExames.
- Podemos pular o primeiro item (Skip 1) na sequência de separação porque é o ID do aluno, não um resultado de exame.

 Dim consultaAlunos = From name In nomes
                                    Let n = name.Split(New Char() {","})
                                    From id In notas
                                    Let n2 = id.Split(New Char() {","})
                                    Where n(2) = n2(0)
                                        Select n2(0) & "," & n(0) & "," & n(1) & " Notas : " & n2(1) & "," &
                                                  n2(2) & "," & n2(3) & "," & n2(4)

- Esta consulta junta dois arquivos textos distintos baseados em valor de ID comum
- Usamos várias cláusulas From ao invés de uma cláusula de JOIN para armazenar os resultados de id.Split.
 

4- Rotina ExibeResultado - Que exibe os dados da consulta LINQ consultaAlunos no listbox.

   Private Sub ExibeResultado(ByVal consulta As IEnumerable(Of String))
        For Each item As String In consulta
            lbAlunos.Items.Add(item)
        Next
        lbAlunos.Items.Add("total de alunos : " + consulta.Count.ToString)
    End Sub

Executando o projeto novamente após esse ajuste teremos o seguinte resultado:

Pegue o projeto completo aqui :  Vbnet_Juntando_Arquivos.zip

"Porque a lei foi dada por Moisés; a graça e a verdade vieram por Jesus Cristo."
Joao 1:17

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