Quick Dev: LINQ Overview

Olá pessoal!   

Neste artigo temos uma visão geral sobre o LINQ, passando pela sua definição, pelos tipos de dados que o suportam, pelos LINQ Providers e pelos estágios da execução de uma consulta LINQ. Por fim, listo também alguns exemplos de consultas com LINQ em diferentes fontes de dados.

Definição

O LINQ (Language Integrated Query) já não é mais novidade, estando disponível desde a versão 3.5 do .NET Framework. Ele veio com o objetivo de adicionar capacidade de pesquisa nativa às linguagens .NET. Com ele podemos pesquisar, filtrar e navegar facilmente sobre coleções de dados, documentos XML, Datasets e até mesmo dados em base de dados SQL Server. Um dos pontos mais interessantes do LINQ é o fato de possibilitar a realização de consultas em todas estas diferentes fontes dados utilizando-se de uma sintaxe padrão. Veja abaixo um exemplo de como seria a recuperação de todos os botões de um determinado formulário (aplicação Windows Forms) através do LINQ e a exibição dos seus nomes em ordem alfabética em um controle ListBox.

        'Esta é a consulta LINQ. Note que a fonte de dados é a coleção de controles do
        'formulário corrente (Me.Controls) e que estou filtrando a consulta para obter
        'apenas os controles do tipo Button. Também estou ordenando a consulta por ordem
        'crescente do nome do controle, através da clausula Order By. Por fim, faço a seleção
        'do que quero que seja atribuído à variável qry.
        Dim qry As IEnumerable(Of Control) = _
            From buttons As Control In Me.Controls _
            Where TypeOf (buttons) Is Button _
            Order By buttons.Text _
            Select buttons
 
        'Neste ponto estou chamando a função Count, que passa a estar disponível em
        'objetos que implementam a interface IEnumerable
        Me.lblStatus.Text = String.Format("{0} botões encontrados", qry.Count)
 
        'Agora basta iterar sobre o resultado da consulta e exibir no ListBox
        Me.ltbLista.Items.Clear()
        For Each btn As Button In qry
            Me.ltbLista.Items.Add(btn.Text)
        Next

Fontes de Dados e Providers

Para que seja possível realizar consultas utilizando o LINQ, é necessário que o dado esteja em uma fonte de dados Linq-Enabled. Como exemplos de tais fontes de dados temos hoje coleções que implementem a interface IEnumerable e IEnumerable(T), blocos XML e documentos XML, Datasets do ADO .NET e bases de dados SQL Server . O acesso aos dados destas fontes de dados é realizado através de LINQ Providers, que são responsáveis por fazer a adaptação da consulta escrita em sintaxe LINQ para a implementação específica da fonte de dados. Como exemplo de LINQ Providers temos o LINQ to Objects, LINQ to XML, LINQ to Dataset, LINQ to Entities e o LINQ to SQL. Neste último, por exemplo, as consultas escritas em LINQ são transformadas em consultas SQL, afinal, a base de dados SQL Server só entende comandos SQL. Veja na imagem a seguir a ilustração desta estrutura descrita.   

Arquitetura LINQ

Arquitetura LINQ - Fonte: http://www.codeproject.com/KB/linq/UnderstandingLINQ.aspx

Estágios de uma consulta LINQ

O processo de acesso a uma fonte de dados com uma consulta LINQ e da obtenção do dado em si ocorre em três estágios. O primeiro é a definição da fonte de dados, que deve ser uma das citadas anteriormente. O segundo é a definição da consulta LINQ em si, onde é definido o dado que se quer obter. O terceiro, por fim, é a execução, a qual geralmente ocorre apenas quando começamos a iterar sobre a consulta através de um loop for each (último passo do exemplo anterior). A consulta é executada ainda em sua definição quando possui funções agregadas (p. ex. Sum, Count e Average) ou quando invocamos métodos como o ToArray e o ToList da variável de definição do range (a variável buttons no exemplo anterior).   

Exemplos

Para finalizar, gostaria de deixar claro a similaridade na estrutura da consulta LINQ nas diferentes fontes de dados. A seguir temos exemplos do LINQ sendo aplicado para filtrar uma coleção de objetos (LINQ to Objects) e para filtrar e obter dados de um documento XML (LINQ to XML). Vou deixar os exemplos do LINQ com ADO .NET (LINQ  to Entities, LINQ to Dataset e LINQ to SQL Server) para um próximo artigo, pois envolvem diversos conceitos que tornariam este artigo muito extenso. No entanto, tenha certeza: A estrutura LINQ é a mesma! O que varia é a forma como trabalhamos com cada um dos providers.  

Linq to Objects 

        'Assuma uma classe simples chamada Player, que contém duas propriedades name (string) e
        'scores (array de integer)
        Dim lsPlayers As New List(Of Player)
 
        'Vamos incluir alguns itens na nossa lista de joradores
        lsPlayers.Add(New Player With {.name = "Nelson", .scores = New Integer() {160, 167, 170}})
        lsPlayers.Add(New Player With {.name = "Jose", .scores = New Integer() {150, 157, 155}})
        lsPlayers.Add(New Player With {.name = "Alfredo", .scores = New Integer() {170, 167, 170}})
        lsPlayers.Add(New Player With {.name = "Coió", .scores = New Integer() {130, 137, 120}})
 
        'Vamos fazer uma consulta nesta lista, obtendo apenas os jogadores cuja
        'média de pontuação seja maior que 160, ordenando o resultado por nome e selecionando
        'todos os campos da entidade Player
        Dim qry As IEnumerable(Of Player) = _
            From plr As Player In lsPlayers _
            Where plr.scores.Average > 160 _
            Order By plr.name _
            Select plr
 
        'Por fim, vamos iterar sobre a consulta, incluindo o seu resultado em um listbox
        Me.ltbLista.Items.Clear()
        For Each plr As Player In qry
            Me.ltbLista.Items.Add(plr.name & vbTab & plr.scores.Average)
        Next

Linq to XML

        'Assuma um documento XML chamado NorthwindProducts.xml, onde o elemento raiz é
        'chamado NorthwindProducts e dentro dele há um array de um elemento do tipo Products
        Dim root As XElement = XElement.Load("NorthwindProducts.xml")
 
        'Carregado o documento, vamos listar todos os produtos, ordenando o resultado
        'pelo nome do produto
        Dim product As IEnumerable(Of XElement) = _
            From el In root.Descendants("Products") _
            Order By (el.Element("ProductName").Value) _
            Select el
 
        'Por fim, vamos preencher um listbox com o nome dos produtos encontrados pela
        'consulta
        Me.ltbListaLINQXML.Items.Clear()
        For Each el In product
            Me.ltbListaLINQXML.Items.Add(el.Element("ProductName").Value)
        Next

Referências

MCTS Self-Paced Training Kit (Exam 70-505): Microsoft .NET Framework 3.5 – Windows Forms Application Development
LINQ  no .NET Framework Developer Center: http://msdn.microsoft.com/en-us/netframework/aa904594.aspx
LINQ no Wikipedia: http://en.wikipedia.org/wiki/Language_Integrated_Query
Understanding LINQ: http://www.codeproject.com/KB/linq/UnderstandingLINQ.aspx

Leave a Reply

 

 

 

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

*