Slides 3
Slides 3
Slides 3
1 2
LINQ
3 4
Introdução ao LINQ
5 6
Introdução à Lambda Functions
São expressões que representam métodos
sem nome e sem modificadores de acesso.
Muitas vezes com o corpo (body)
Dentro do universo de expressões lambdas,
representado em uma única linha. Uma
vamos utilizar dois Types especiais
expressão lambda possui a seguinte
(delegates) no C#
anatomia:
(input-parameters) expression
(input-parameters) { <sequência de
códigos> }
7 8
9 10
Sintaxe e operadores
11 12
var listaValores = new List<int>();
Podemos encadear os operadores uns com os
outros de forma que eles representem uma
//popula a lista com alguns valores
for (int i = 0; i < 10; i++)
{
listaValores.Add(i); “pipeline” (esteira ou caminho de fluxo).
}
Com os operadores LINQ podemos:
//Exemplo de filtro com o operador WHERE:
var listaFiltradaWhere = listaValores.Where(p => p > 5); //6,7,8,9 Filtrar
//Exemplo do operador First, encontrando o elemento:
var elemento2 = listaValores.First(v => v == 2); // 2 Ordenar
//Exemplo do operador FirstOrDefault, em um elemento não existente:
var elementoDefault = listaValores.FirstOrDefault(v => v > 10); // 0
Agregar
(valor default do int)
Agrupar
//Exemplo dos operadores: Any e Max
if (listaValores.Any())
{
Unir
var maxValue = listaValores.Max(); // 9
} Converter
13 14
15 16
Depois temos o operador “OrderBy” que Depois temos o operador “Select” que realiza
produz uma nova versão da lista ordenada: um projeção para os elementos da lista. Para
cada elemento, ele executa uma Lambda
OrderBy<TSource>(Func<TSource, TKey> Function que pode transformar o valor do
keySelector); elemento (trataremos dos detalhes dele mais
O seu resultado é uma nova lista do mesmo adiante)
Type, com seus elementos ordenados, O seu resultado é uma nova lista, com os
segundo o valor retornado pela Func: elementos convertidos para maiúsculo
“keySelector” (ToUpper())
17 18
Entendendo a pipeline Quando os operadores de consulta LINQ são
encadeados, a consulta completa se assemelha a
uma esteira de linha de produção (pipeline),
onde a coleção de saída de um operador é a
“Um operador de consulta nunca altera a
coleção de entrada para o próximo:
sequência de entrada; ao invés disso retorna
uma nova sequência (coleção). Isso é
consistente com o paradigma funcional de
programação, a partir do qual o LINQ foi
inspirado” (Albahari, 2017, p. 355)
19 20
porque seu resultado pode ser de um Type //Utilizando o select para fazer uma Projeção (modificando o tipo de retorno da lista)
diferente do Type da coleção original //de uma lista de string, transformamos em uma lista de inteiros
IEnumerable<int> queryResultSelect = nomes.Select(n => n.Length);
21 22
23 24
Vamos entender melhor: uma das diferenças
Vejamos o mesmo exemplo de query LINQ que
notáveis entre as sintaxes nesse nosso exemplo é o
fizemos anteriormente em Fluent Syntax agora uso do “from” seguido por uma variável, em nosso
em Query Expression caso o “n”. Essa variável recebe o nome formal de:
“variável de intervalo”. Ela representa um elemento
string[] nomes = { "Tom", "Huck", "Harry", "Mary", "Jay" };
do array, assim como no “foreach”:
IEnumerable<string> query = from n in nomes
where n.Contains("a") // Filtra os elementos foreach(var n in nomes){...}
orderby n.Length // Ordena pelo tamanho
select n.ToUpper(); // Converte para string ToUpper (projeção)
from n in nomes // n é nossa variável de intervalo
foreach (string nome in query) where n.Contains("a") // n = elemento direto do array
{ orderby n.Length // n = elemento já filtrado pelo where
Console.WriteLine(nome); //Output no console:
} JAY select n.ToUpper() // n = elemento já ordenado pelo orderby
MARY
HARRY
nomes.Where(n => n.Contains("a")) // variável de escopo local n
.OrderBy(n => n.Length) // variável de escopo local n
.Select(n => n.ToUpper()) // variável de escopo local n
25 26
Toda query escrita em Query Expression pode var quantidadeLetraA = (from n in nomes
where n.Contains("a")
ser convertida em uma query usando Fluent select n).Count(); // 3
porém, não é verdadeiro (...) // Query mais complexa com mix entre as sintaxes, subqueries e projection
var mixQueries = (from n in nomes
join nomeY in nomes.Where(y => y.Contains("y")) on n equals nomeY
where n.Count() > 3
select n.ToUpper()).OrderByDescending(x=> x); // MARY, HARRY
27 28
Deffered exectuion
29 30
Reavaliação/reexecução
A execução tardia traz outras consequências
interessantes, como uma query LINQ não
executa no momento que é construída, podemos
Vamos ver na prática o comportamento de reutilizá-la várias vezes!
“Defered Execution/Lazy Execution” var numeros2 = new List<int>() { 1, 2 };
var queryExemplo2 = numeros2.Select(n => n * 10);
//Limpamos a lista!
numeros2.Clear();
31 32
pode ser computacionalmente intensiva, seja // o ToList força a enumeração e executa a query imediatamente
var listaMultiplicadaPor10 = numeros3.Select(n => n * 10).ToList();
33 34
Categorias de operadores
35 36
Método Descrição Equivalência em SQL
Operadores de filtro Retorna um subset (subcoleção) de elementos que
Where WHERE
satisfazem uma determinada condição
37 38
39 40
41 42
Operadores de combinação (Join) Método Descrição Equivalência em SQL
Join Aplica um estratégia chamada de “Lookup” INNER JOIN
para dar match em elementos das duas
coleções, produzindo como output um coleção
“plana” (flat)
Os operadores/métodos de “Join” do LINQ GroupJoin Similar ao Join, com a diferença que produz
um output de coleção hierárquica
INNER JOIN, LEFT
OUTER JOIN
podem ser muito úteis para combinar Zip Enumera duas coleções simultaneamente, N/A
aplicando uma técnica conhecida como
resultados de coleções diferentes. Você deve “Zipper” (por lembrar um zíper de roupa);
usá-los em situações nas quais o resultado aplicando uma Lambda Function que combina
os elementos das coleções. Produz um
que precisa seja fruto da combinação entre retorno utilizando tuplas, no qual cada tupla é
a combinação do elemento da primeira
coleções coleção com o elemento da segunda coleção,
conforme a Lambda fornecida
43 44
Operadores de ordenação
Retornam sempre os mesmos elementos,
porém em ordens diferentes
Para operações de combinação (Join), o Método Descrição Equivalência
em SQL
uso da sintaxe de consulta LINQ Query OrderBy, ThenBy Ordena a coleção em ORDER BY
Expression é muito simples, vamos um forma descendente
OrderByDescending, Ordena a coleção em= ORDER
string[] nomes BY ... "Paulo", "Antonio", "Maria"
{ "João", "Silva",
45 46
sumariamente são heranças de ToArray Converte a coleção para T[] (array do type T)
ToList Converte a coleção para List<T>
IEnumerable<T>. Existem alguns operadores ToDictionary Converte a coleção para Dictionary<Tkey,Tvalue>
que podem modificar o Type de “destino” ToLookup Converte a coleção para um Ilookup<Tkey,Telement>
47 48
Operadores de agregação Método Descrição
Equivalência em
SQL
Retorna a quantidade de elementos na
Count, coleção. Pode executar um "Where"
Count(....)
LongCount interno, se for passado uma Lambda
Function de filtro como parâmetro
Retorna o menor ou maior elemento de
Min, Max MIN (...), MAX(...)
uma coleção
Sempre retornaram um valor discreto, isto é,
string[] nomes = { "João", "Silva", "Paulo", "Antonio", "Maria",
"Joana"
Calcula a };
somatória ou a média dos valores
Sum, Average SUM (...), AVG(...)
um valor numérico simples (nunca uma de elementos de umaaocoleção
// equivalente Lenght ou Count
Executaint
umaqtdColecao
agregação= nomes.Count();
matemática,
coleção) como resultado recebendo uma os
// Conta Lambda Function como
a minusculos
Aggregate N/A
parâmetro
int para computá-la
qtdLetraA a cada
= nomes.Sum(n => n.Count(c => c == 'a'));
elemento
// Max e Min
Fonte: O autor, 2021 int[] numeros = { 28, 32, 14 };
int menor = numeros.Min(); // 14;
int maior = numeros.Max(); // 32
49 50