Dicas sobre .NET: consultas LINQ em objetos compostos

Muitas consultas LINQ envolvem apenas a seleção de propriedades no conjunto de objetos que se está manipulando. Este procedimento costuma se assemelhar ao uso da cláusula SELECT em uma tabela relacional convencional.

Embora a prática citada seja a mais comum em aplicações .NET, há casos nos quais objetos contam com propriedades que também são coleções. E eis que surge a necessidade de se retornar os valores dos objetos-filhos. Como proceder nestes casos?

Ainda assim será possível o uso de uma consulta LINQ nestes cenários. Para exemplificar isto serão utilizadas duas classes (Cidade e Estado), cuja implementação está na próxima listagem:

[code language=”csharp”]
using System.Collections.Generic;

namespace TesteLINQ
{
 public class Cidade
 {
 public string Nome { get; set; }
 public string DDD { get; set; }
 }

public class Estado
 {
 public string Nome { get; set; }
 public string Sigla { get; set; }
 public List<Cidade> Cidades { get; }

public Estado()
 {
 this.Cidades = new List<Cidade>();
 }
 }
}
[/code]

O trecho de código a seguir traz um exemplo de preenchimento de uma coleção de estados, com suas respectivas cidades:

[code language=”csharp”]

var estados = new List<Estado>();

Estado estadoSP = new Estado();
estadoSP.Nome = “Sao Paulo”;
estadoSP.Sigla = “SP”;

estadoSP.Cidades.Add(new Cidade()
{
 Nome = “Sao Paulo”,
 DDD = “011”
});

estadoSP.Cidades.Add(new Cidade()
{
 Nome = “Santos”,
 DDD = “013”
});

estadoSP.Cidades.Add(new Cidade()
{
 Nome = “Sorocaba”,
 DDD = “015”
});

estados.Add(estadoSP);

Estado estadoMG = new Estado();
estadoMG.Nome = “Minas Gerais”;
estadoMG.Sigla = “MG”;

estadoMG.Cidades.Add(new Cidade()
{
 Nome = “Belo Horizonte”,
 DDD = “031”
});

estados.Add(estadoMG);


[/code]

Para produzir como resultado uma listagem contendo as cidades e seus estados correspondentes será utilizada a consulta LINQ detalhada na listagem seguinte:

  • Nota-se o uso da cláusula from por 2 vezes, selecionando primeiramente os estados e na sequência as cidades;
  • O retorno serão objetos baseados em um tipo anônimo gerado por meio da palavra-chave new, com um resultado similar ao de um INNER JOIN de uma expressão SQL convencional.

[code language=”csharp”]

var resultado = from e in estados
 from c in e.Cidades
 select new
 {
 NomeCidade = c.Nome,
 c.DDD,
 CodEstado = e.Sigla
 };


[/code]

Por fim, o próximo trecho de código exibirá em tela o resultado da consulta realizada na listagem anterior:

[code language=”csharp”]

var cidades = resultado.ToList();
foreach (var cidade in cidades)
{
 Console.WriteLine(
 $”{cidade.NomeCidade}-{cidade.CodEstado} DDD: {cidade.DDD}”);
}


[/code]

Executando este bloco de instruções aparecerá então uma tela como a indicada na próxima imagem:

groffe-linq-01

Maiores informações sobre expressões LINQ podem ser encontradas na seção de Referências.

Espero que este conteúdo possa ter sido útil.

Até uma próxima oportunidade!

Referências

LINQ Query Expressions (C# Programming Guide)
https://msdn.microsoft.com/en-us/library/bb397676.aspx