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




