20/04/2018
LINQ to Objects - Realizando Consulta em Coleções de objetos
LINQ to Objects - Realizando Consultas em Coleções Coleções de objetos objetos " consultas"" sobre coleções de objetos. Para facilitar a LINQ to Objects permite aos desenvolvedores da plataforma .NET escrever "consultas Microsoft fornece um grande conjunto de operadores de consulta, e esses operadores oferecem uma profundidade semelhante à funcionalidade que temos com a linguagem SQL trabalhando com banco de dados relacional. Neste artigo vamos rever alguns conceitos chaves da LINQ da LINQ to Objects e Objects e mostrar na prática a sua utilização criando consultas em coleções de objetos para lembrar a sintaxe usada nessas operações. operações. Nota: Não Confunda LINQ to Objects com LINQ to Entities, Entities, elas são diferentes.
Tradicionalmente, trabalhar com coleções de objetos significava escrever um monte de código usando laços for ou foreach para percorrer a coleção, usar ifs para filtrar durante a execução e manter uma soma parcial de uma propriedade total. A LINQ nos libera de ter que escrever o código usando muitos laços; ela permite escrever consultas que filtram uma lista que façam cálculos usando funções de agregação de elementos em uma coleção em memória. Podemos escrever consultas contra qualquer tipo de coleção que implementa uma interface IEnumerable
, o que a grande parte das classes de coleções da plataforma .NET implementa, inclusive os arrays. Objetivos
Revisar conceitos da LINQ to Objects e realizar consultas em coleções de objetos Aprendizado
Conceitos sobre LINQ to Objects Criar coleções de objetos Realizar consultas usando os principais operadores da LINQ Recursos usados
Visual Studio 2013 Express for windows desktop Linguagem VB .NET
Preparando o ambiente - Criando o projeto no Visual Studio 2013
20/04/2018
LINQ to Objects - Realizando Consulta em Coleções de objetos
Abra o Visual Studio 2013 Express for Windows Desktop e clique em New Project ; Selecione o template Visual C# -> Windows -> Console Application e informe o nome LINQ_Objects_2 e clique em OK; Com o projeto criado vamos incluir duas classes na solução : Contato.vb - Classe que contém informações sobre contatos : Nome, Sobrenome, Email, Telefone, Nascimento e Estado LogChamadas.vb - Classe que contém informações sobre ligações telefônicas : Numero, Duracao, Recebida, Data
No menu PROJECT clique em Add Class e informe o nome Contato.vb e a seguir inclua o seguinte código nesta classe: Public Class Contato Public Property Nome() As String Public Property Sobrenome() As String Public Property Email() As String Public Property Telefone() As String Public Property Nascimento() As DateTime Public Property Estado() As String Public Shared Function DadosTeste() As List(Of Contato) Return New List(Of Contato)() From { _ New Contato() With { _ .Nome = "José Carlos", .Sobrenome = "Macoratti", .Nascimento = New DateTime(1975, 10, 19), .Telefone = "8983 8858", .Email = "[email protected]", .Estado = "SP" _ }, _ New Contato() With { .Nome = "Armando", .Sobrenome = "Soares", .Nascimento = New DateTime(1973, 12, 9), .Telefone = "9553 8487", .Email = "[email protected]", .Estado = "RJ" _ }, _ New Contato() With { .Nome = "Natalia", .Sobrenome = "Bueno", .Nascimento = New DateTime(1959, 10, 3), .Telefone = "8999 1154", .Email = "[email protected]",
.Estado = "MG" _
}, _ New Contato() With { .Nome = "Jefferson", .Sobrenome = "Chaves", .Nascimento = New DateTime(1980, 12, 16), .Telefone = "9602 6774", .Email = "[email protected]", .Estado = "SP" _ }, _ New Contato() With { .Nome = "Carla", .Sobrenome = "Andrade", .Nascimento = New DateTime(1985, 2, 10), .Telefone = "8303 6030", .Email = "[email protected]", .Estado = "PR" _ }, _ New Contato() With { .Nome = "Jonas", .Sobrenome = "Kagel", .Nasciment o = New DateTime(1960, 2, 20), .Telefone = "9907 5462", .Email = "[email protected]" , .Estado = "RJ" _ }, _ New Contato() With { .Nome = "Maria", .Sobrenome = "Siqueira", _ .Nascimento = New DateTime(1991, 10, 21), _ .Telefone = "9918 2789", _ .Email = "[email protected]", _ .Estado = "SP" _ }, _ New Contato() With { .Nome = "Bruno", .Sobrenome = "Sanches", _ .Nascimento = New DateTime(1946, 5, 18), _ .Telefone = "8715 9920", _
20/04/2018
LINQ to Objects - Realizando Consulta em Coleções de objetos
.Email = "[email protected]", _ .Estado = "MG" _ }, _ New Contato() With { Nome = "Mario", .Sobrenome = "Ferreira", .Nascimento = New DateTime(1977, 9, 17), .Telefone = "9902 3644", .Email = "[email protected]", .Estado = "RS" _ }, _ New Contato() With { .Nome = "Ariel", .Sobrenome = "Santos", .Nascimento = New DateTime(1962, 5, 23), .Telefone = "9837 1656", .Email = "[email protected]", .Estado = "RJ" _ }_ } End Function End Class
Na classe Contato declaramos 6 propriedades e definimos os dados para uma coleção de objetos do tipo Contato a ser criada em memória. A seguir, menu PROJECT clique em Add Class e informe o nome LogChamadas.vb e a seguir inclua o seguinte código nesta classe: Public Class LogChamadas Public Property Numero() As String Public Property Duracao() As Integer Public Property Recebida() As Boolean Public Property Data() As DateTime Public Shared Function DadosTeste() As List(Of LogChamadas) Return New List(Of LogChamadas)() From { _ New LogChamadas() With { _ .Numero = "9553 8487", _ .Duracao = 2, _ .Recebida = True, _ .Data = New DateTime(2014, 8, 7, 8, 12, 0) _ }, _ New LogChamadas() With { _ .Numero = "8999 1154", _ .Duracao = 15, _ .Recebida = True, _ .Data = New DateTime(2014, 8, 7, 9, 23, 0) _ }, _ New LogChamadas() With { _ .Numero = "9602 6774", _ .Duracao = 1, _ .Recebida = False, _ .Data = New DateTime(2014, 8, 7, 10, 5, 0) _ }, _ New LogChamadas() With { _ .Numero = "8303 6030", _ .Duracao = 2, _
20/04/2018
LINQ to Objects - Realizando Consulta em Coleções de objetos
.Recebida = False, _ .Data = New DateTime(2014, 8, 7, 10, 35, 0) _ }, _ New LogChamadas() With { _ .Numero = "9907 5462", _ .Duracao = 4, _ .Recebida = True, _ .Data = New DateTime(2014, 8, 7, 11, 15, 0) _ }, _ New LogChamadas() With { _ .Numero = "9553 8487", _ .Duracao = 15, _ .Recebida = False, _ .Data = New DateTime(2014, 8, 7, 13, 12, 0) _ }, _ New LogChamadas() With { _ .Numero = "9553 8487", _ .Duracao = 3, _ .Recebida = True, _ .Data = New DateTime(2014, 8, 7, 13, 47, 0) _ }, _ New LogChamadas() With { _ .Numero = "9907 5462", _ .Duracao = 1, _ .Recebida = False, _ .Data = New DateTime(2014, 8, 7, 20, 34, 0) _ }, _ New LogChamadas() With { _ .Numero = "9907 5462", _ .Duracao = 3, _ .Recebida = False, _ .Data = New DateTime(2014, 8, 8, 10, 10, 0) _ }, _ New LogChamadas() With { _ .Numero = "8303 6030", _ .Duracao = 23, _ .Recebida = False, _ .Data = New DateTime(2014, 8, 8, 10, 40, 0) _ }, _ New LogChamadas() With { _ .Numero = "9918 2789", _ .Duracao = 3, _ .Recebida = False, _ .Data = New DateTime(2014, 8, 8, 14, 0, 0) _
20/04/2018
LINQ to Objects - Realizando Consulta em Coleções de objetos
}, _ New LogChamadas() With { _ .Numero = "9918 2789", _ .Duracao = 7, _ .Recebida = True, _ .Data = New DateTime(2014, 8, 8, 14, 37, 0) _ }, _ New LogChamadas() With { _ .Numero = "9902 3644", _ .Duracao = 6, _ .Recebida = True, _ .Data = New DateTime(2014, 8, 8, 15, 23, 0) _ }, _ New LogChamadas() With { _ .Numero = "9602 6774", _ .Duracao = 20, _ .Recebida = True, _ .Data = New DateTime(2014, 8, 8, 17, 12, 0) _ }, _ New LogChamadas() With { _ .Numero = "9553 8487", _ .Duracao = 5, _ .Recebida = True, _ .Data = New DateTime(2014, 7, 12, 8, 12, 0) _ }, _ New LogChamadas() With { _ .Numero = "8999 1154", _ .Duracao = 12, _ .Recebida = True, _ .Data = New DateTime(2014, 6, 14, 9, 23, 0) _ }, _ New LogChamadas() With { _ .Numero = "9602 6774", _ .Duracao = 10, _ .Recebida = False, _ .Data = New DateTime(2014, 7, 9, 10, 5, 0) _ }, _ New LogChamadas() With { _ .Numero = "8303 6030", _ .Duracao = 22, _ .Recebida = False, _ .Data = New DateTime(2014, 7, 5, 10, 35, 0) _ }, _ New LogChamadas() With { _
20/04/2018
LINQ to Objects - Realizando Consulta em Coleções de objetos
.Numero = "9907 5462", _ .Duracao = 9, _ .Recebida = True, _ .Data = New DateTime(2014, 6, 7, 11, 15, 0) _ }, _ New LogChamadas() With { _ .Numero = "9553 8487", _ .Duracao = 10, _ .Recebida = False, _ .Data = New DateTime(2014, 6, 7, 13, 12, 0) _ }, _ New LogChamadas() With { _ .Numero = "9553 8487", _ .Duracao = 21, _ .Recebida = True, _ .Data = New DateTime(2014, 7, 7, 13, 47, 0) _ }, _ New LogChamadas() With { _ .Numero = "9907 5462", _ .Duracao = 7, _ .Recebida = False, _ .Data = New DateTime(2014, 7, 7, 20, 34, 0) _ }, _ New LogChamadas() With { _ .Numero = "9907 5462", _ .Duracao = 2, _ .Recebida = False, _ .Data = New DateTime(2014, 6, 8, 10, 10, 0) _ }, _ New LogChamadas() With { _ .Numero = "8303 6030", _ .Duracao = 3, _ .Recebida = False, _ .Data = New DateTime(2014, 6, 8, 10, 40, 0) _ }, _ New LogChamadas() With { _ .Numero = "9918 2789", _ .Duracao = 32, _ .Recebida = False, _ .Data = New DateTime(2014, 7, 8, 14, 0, 0) _ }, _ New LogChamadas() With { _ .Numero = "9918 2789", _ .Duracao = 13, _
20/04/2018
LINQ to Objects - Realizando Consulta em Coleções de objetos
.Recebida = True, _ .Data = New DateTime(2014, 7, 8, 14, 37, 0) _ }, _ New LogChamadas() With { _ .Numero = "9902 3644", _ .Duracao = 16, _ .Recebida = True, _ .Data = New DateTime(2014, 5, 8, 15, 23, 0) _ }, _ New LogChamadas() With { _ .Numero = "9602 6774", _ .Duracao = 24, _ .Recebida = True, _ .Data = New DateTime(2014, 6, 8, 17, 12, 0) _ }_ } End Function End Class
Na classe LogChamadas declaramos 4 propriedades e definimos os dados para uma coleção de objetos do tipo LogChamadas a ser criada em memória que representa as ligações feitas pelos contatos. Existem portanto uma relação entre as duas classes que iremos usar para realizar a junção entre as coleções.
Consultando coleções de objetos Vamos agora definir 4 consultas LINQ to Objects para mostrar como podemos obter informações de coleções. No arquivo Module1.vb da nossa solução vamos declarar a chamada para 4 métodos que serão criados posteriormente conforme o código a seguir: Sub Main() Exemplo1() 'Exemplo2() 'Exemplo3() 'Exemplo4() End Sub A seguir vamos criar um método que irá ser executado em todas as consultas e que irá criar um pequeno cabeçalho para identificar a consulta: Public Sub cabecalho(texto As String) Console.WriteLine("Macoratti .net") Console.WriteLine("--------------------------------------------------") Console.WriteLine(texto)
20/04/2018
LINQ to Objects - Realizando Consulta em Coleções de objetos
Console.WriteLine("--------------------------------------------------") Console.WriteLine("") End Sub
Vamos agora criar cada uma das consultas: 1- Retornando uma lista de contatos com idade inferior a 45 anos: Public Sub Exemplo1() cabecalho("Lista Contatos com idade inferior a 45 anos") Dim contatos As List(Of Contato) = Contato.DadosTeste() Dim q = From c In contatos Where c.Nascimento.AddYears(45) > DateTime.Now Order By c.Nascimento Descending Select String.Format("{0} {1} , nascimento : {2}", c.Nome, c.Sobrenome, c.Nascimento.ToString("dd-MMM-yyyy")) For Each s As String In q Console.WriteLine(s) Next
Console.ReadKey() End Sub
Observe que na cláusula Select usamos o método String.Format() para formatar a saída a consulta. 2- Além de filtrar itens em uma coleção e projetar os resultados, a LINQ oferece a capacidade de agrupar os itens de coleta em qualquer forma que você precisar. Nesta consulta agrupamos os contatos por Estado de origem: Public Sub Exemplo2() cabecalho("Lista Contatos por Estado") Dim contatos As List(Of Contato) = Contato.DadosTeste() Dim consulta = From c In contatos Group c By c.Estado Into ContatosGrupo = Group For Each grupo In consulta Console.WriteLine("Estado : " + grupo.Estado) For Each c In grupo.ContatosGrupo Console.WriteLine(" {0} {1}", c.Nome, c.Sobrenome) Next Next
Console.ReadKey() End Sub
20/04/2018
LINQ to Objects - Realizando Consulta em Coleções de objetos
3- Um aspecto fundamental no acesso aos dados relacionados é o conceito de junção dos dados relacionados.
Os Sistemas de banco de dados relacional (como o Microsoft SQL Server) têm um poderoso recursos para realizar junções que permitem escrever consultas contra dados normalizados, o que é um termo chique para a "não repetir os dados" por separar os dados entre várias tabelas vinculando-os com um valor comum. A LINQ permite fazer a junção( joi n ) de várias coleções de objetos em conjunto, utilizando a sintaxe similar à SQL, como vemos na consulta a seguir: Public Sub Exemplo3() cabecalho("Consulta com junção de duas Coleções com base no numero do telefone") Dim contatos As List(Of Contato) = Contato.DadosTeste() Dim chamadas As List(Of LogChamadas) = LogChamadas.DadosTeste() Dim consulta = From ligacao In chamadas Join contato In contatos On _ ligacao.Numero Equals contato.Telefone _ Select New With { _ contato.Nome, _ contato.Sobrenome, _ ligacao.Data, _ ligacao.Duracao _ } For Each c In consulta Console.WriteLine(" {0} – {1} {2} ({3} min)", c.Data.ToString("dd MMM HH:m"), c.Nome, c.Sobrenome, c.Duracao) Next
Console.ReadKey() End Sub
4- Para demonstrar o poder da LINQ to Objects a consulta a seguir totaliza os dados a partir de duas coleções em memória usando junções, agrupamentos e ainda os operadores agregados (SUM, COUNT, AVG, etc.) na cláusula Select : Public Sub Exemplo4() cabecalho("Resumo do log de ligações, filtrando, ordenando, agrupando, " & vbLf & _ "juntando e selecionando usando valores agregados") Dim contatos As List(Of Contato) = Contato.DadosTeste() Dim chamadas As List(Of LogChamadas) = LogChamadas.DadosTeste() Dim consulta = From ligacao In chamadas Where ligacao.Recebida = True Group ligacao By ligacao.Numero Into lig = Group Join contato In contatos On Numero Equals contato.Telefone
20/04/2018
LINQ to Objects - Realizando Consulta em Coleções de objetos
Order By contato.Nome, contato.Sobrenome Select New With { _ contato.Nome, _ contato.Sobrenome, _ .Conta = lig.Count(), _ .Media = lig.Average(Function(c) c.Duracao), _ .Total = lig.Sum(Function(c) c.Duracao) _ } For Each ligacao In consulta Console.WriteLine("{0} {1} - ligações: {2}, Tempo: {3} mins, Média: {4} mins ", _ ligacao.Nome, ligacao.Sobrenome, ligacao.Conta, ligacao.Total, Math.Round(ligacao.Media, 2)) Next Console.ReadKey() End Sub
Percebeu que de forma quase intuitiva criamos as consultas usando a sintaxe do LINQ to Objects em coleções de memórias. Pegue o projeto completo aqui:
LINQ_Objects_2.zip
João 3:21 Mas quem pratica a verdade vem para a luz, a fim de que seja manifesto que as suas obras são feitas em Deus. (disse Jesus) Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !
Quer migrar para o VB .NET ? Veja mais sistemas completos para a plataforma .NET no Super DVD .NET , confira...
Curso Básico VB .NET - Vídeo Aulas Quer aprender C# ?? Chegou o Super DVD C# com exclusivo material de suporte e vídeo aulas com curso básico sobre C#.
Curso C# Basico - Video Aulas
Gostou ? Referências:
Compartilhe no Facebook
Compartilhe no Twitter
20/04/2018
LINQ to Objects - Realizando Consulta em Coleções de objetos
Seção VB .NET do Site Macoratti.net Super DVD .NET - A sua porta de entrada na plataforma .NET Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C# Seção C# do site Macoratti.net Super DVD C# Super DVD Visual Basic Curso Básico VB .NET - Vídeo Aulas Curso C# Básico - Vídeo Aulas Apresentando LINQ - Macoratti.net Um pouquinho mais sobre LINQ - Macoratti.net NET - LINQ a seu dispor - Sintaxe e Operadores - Macoratti LINQ - LINQ to Objects - o retorno - Macoratti.net Apresentando LINQ to Entities - Macoratti.net José Carlos Macoratti