LINQ - Operações de interseção e União


O que é LINQ ?

- LINQ - Language integrated Query - é um conjunto de recursos introduzidos no .NET Framework 3.5 que permitem a realização de consultas diretamente em base de dados , documentos XML , estrutura de dados , coleção de objetos ,etc. usando uma sintaxe parecida com a linguagem SQL.

Este artigo mostra como realizar operações de interseção e união com LINQ.

O que é uma operação Union com LINQ ?

"Combina os dados a partir de duas ou mais tabelas e mostra-los como um único conjunto de resultado"

Abra o Visual Basic 2010 Express Edition e crie um novo projeto (File-> New Project) do tipo Windows Forms Application com o nome LINQ_Union_Intersecao;

No formulário form1.vb inclua os seguintes controles :

Conforme o leiaute da figura abaixo:

Vamos definir o código do formulário começando com a definição do namespace:

Imports System.IO

No evento Click do botão - btnPasta - que irá permitir ao usuário selecionar uma pasta no sistema local, inclua o código abaixo:

  Private Sub btnPasta_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPasta.Click
        ' cria um objeto FolderBrowserDialog
        Dim FolderBrowserDialog1 As New FolderBrowserDialog

        ' cria uma janela de dialogo
        With FolderBrowserDialog1
            ' Desktop é a pasta rais no dialogo
            .RootFolder = Environment.SpecialFolder.Desktop
            ' seleciona a pata c:\ na entrada
            .SelectedPath = "c:\"
            ' exibe uma mensagem ao usuário
            .Description = "Selecione uma pasta"
            If .ShowDialog = DialogResult.OK Then
                ' atribui a seleção da pasta ao textbox
                txtDiretorio.Text = .SelectedPath
            End If
        End With
    End Sub

No código estamos usando a classe FolderBrowserDialog que Solicita ao usuário para selecionar uma pasta.

Essa classe fornece uma maneira de solicitar ao usuário para procurar, criar e, eventualmente, selecionar uma pasta. Use essa classe quando você quer permitir que o usuário selecione pastas e não arquivos. A navegação nas pastas é feita por meio de um controle de árvore. Somente as pastas do sistema de arquivos podem ser selecionadas; não é possível selecionar pastas virtuais.

Normalmente, após a criação de uma nova instância da classe FolderBrowserDialog, você pode definir a RootFolder para o local a partir do qual você começa a navegar. Opcionalmente, você pode definir o SelectedPath em um caminho absoluto de uma subpasta de RootFolder que será selecionada inicialmente.

Você também pode definir a propriedade Description para fornecer instruções adicionais ao usuário. Finalmente, chame o método ShowDialog para exibir a caixa de diálogo ao usuário. Quando a caixa de diálogo for fechada e a caixa de diálogo resultante da ShowDialog for DialogResult.OK, o SelectedPath será uma cadeia de caracteres que contém o caminho para a pasta selecionada.

No exemplo atribuímos esta valor a caixa de texto txtDiretorio.

No evento Click do botão - Exibir Arquivos - inclua o código que usará a consulta LINQ exibindo informações sobre eles no datagridview:

Private Sub btnExibirArquivos_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExibirArquivos.Click
        Dim dir As DirectoryInfo = New DirectoryInfo(txtDiretorio.Text)

        If txtDiretorio.Text = String.Empty Then
            Dim resultado = From arquivo In dir.GetFiles()
                                    Order By (arquivo.Extension)
                                    Select New With {arquivo.Name, arquivo.Extension, arquivo.Length, arquivo.FullName}
            gdvDetalhes.DataSource = resultado.ToList
        Else
            Dim resultado = From arquivo In dir.GetFiles()
                                     Where arquivo.Name.ToLower().Contains(txtFiltro.Text.ToLower())
                                     Order By (arquivo.Extension)
                                     Select New With {arquivo.Name, arquivo.Extension, arquivo.Length, arquivo.FullName}
            gdvDetalhes.DataSource = resultado.ToList
        End If

    End Sub

Neste código estamos efetuando duas consultas LINQ , no caso estamos usando LINQ to SQL, com base na informação do usuário:

1- A primeira exibe todos os arquivos da pasta ordenados pela extensão:

Dim resultado = From arquivo In dir.GetFiles()
                         Order By (arquivo.Extension)
                         Select New With {arquivo.Name, arquivo.Extension, arquivo.Length, arquivo.FullName}

2- A segunda exibe os arquivos da pasta com base no filtro informado na caixa de texto txtFiltro ordenados pela extensão:

Dim resultado = From arquivo In dir.GetFiles()
                        Where arquivo.Name.ToLower().Contains(txtFiltro.Text.ToLower())
                        Order By (arquivo.Extension)
                        Select New With {arquivo.Name, arquivo.Extension, arquivo.Length, arquivo.FullName}

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

SQL  Select <info>From <fonte>
LINQ  From <fonte> Select <info>

Ambas as consultas LINQ To SQL iniciam com a cláusula From e em seguida o operador de condição Where depois ordenação com Order By e, no final o operador de seleção Select.

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.)

Poderíamos exibir mais informações sobre os arquivos como LastAccessTime, LastWriteTime, CreationTime, IsReadyOnly, etc. bastando para isso definirmos isso na cláusula Select new with;

Obs: A cláusula new na instrução SELECT esta criando objetos anônimos definidos após a cláusula With.

Executando o projeto iremos obter:

Pegue o projeto completo aqui: ConsultaArquivos.zip

Rom 1:18 Pois do céu é revelada a ira de Deus contra toda a impiedade e injustiça dos homens que detêm a verdade em injustiça.

Rom 1:19 Porquanto, o que de Deus se pode conhecer, neles se manifesta, porque Deus lho manifestou.

Rom 1:20 Pois os seus atributos invisíveis, o seu eterno poder e divindade, são claramente vistos desde a criação do mundo, sendo percebidos mediante as coisas criadas, de modo que eles são inescusáveis;

Rom 1:21 porquanto, tendo conhecido a Deus, contudo não o glorificaram como Deus, nem lhe deram graças, antes nas suas especulações se desvaneceram, e o seu coração insensato se obscureceu.

Referências:


José Carlos Macoratti