Introdução ao LINQ no C#
Facilitador
Fernando Padoan
Engenheiro de Sistemas
http://www.cesar.org.br/
O que é o LINQ
"Language Integrated Query"
Adicionado ao .Net em 2007
Permite criar consultas a dados utilizando as
linguagens suportadas pelo .Net Framework
Inspirado em SQL e Haskell
Exemplo de Consulta
string[] linguagens = new string[5] { "C#",
"VB", "Javascript", "C++", "F#" };
var nomesCurtos =
from li in linguagens
where li.Length < 4
select li;
foreach (string nome in nomesCurtos)
{
Console.WriteLine(nome);
}
C#
VB
C++
F#
Data Source
string[] linguagens = new string[5] {
"C#",
"VB",
"Javascript",
"C++",
"F#"
};
Array
IEnumerable<T>
apenas em runtime
Query
var nomesCurtos =
from li in linguagens
where li.Length < 4
select li;
inferência de tipo
fonte dos dados
filtragem
tipo do retorno
Até este momento, a consulta não é executada, e
nenhum dado é retornado!
Deferred Execution
foreach (string nome in nomesCurtos)
{
Console.WriteLine(nome);
}
Execução da consulta ocorre ao iterar pelo objeto de
consulta em um foreach.
Execução Imediata
int quantos = nomesCurtos.Count();
Outros exemplos:
.ToArray(), .ToList(), .First()...
Tipos de Dados
"Queryable data types":
IEnumerable
IEnumerable<T>
IQueryable<T>
... ou qualquer outro tipo que implemente
IEnumerable<T>.
Tipos de Dados na Consulta
IEnumerable<string> nomesCurtos =
from li in linguagens
where li.Length < 4
select li;
Mais exemplos:
Query vs. Method Syntax
int[] numeros = { 1, 2, 3, 5, 8, 13, 21, 34
};
IEnumerable<int> pares = // query???
foreach (int i in pares)
{
Console.Write(i + " ");
}
Query Syntax
IEnumerable<int> pares =
from num in numeros
where num % 2 == 0
orderby num
select num;
Method Syntax
IEnumerable<int> pares = numeros.Where(num
=> num % 2 == 0).OrderBy(n => n);
Extension methods
Lambda expressions
LINQ Extension Methods
namespace System.Linq
{
public static class Enumerable
{
// ...
public static IEnumerable<TSource> Where<TSource>(
this IEnumerable<TSource> source,
Func<TSource, bool> predicate)
// ...
}
// ...
}
Lambda Expressions
"num => num % 2 == 0"
"n => n"
"Func<TSource, bool> predicate"
"=>" : "goes to"
Operações de Consulta
Obtenção de dados:
var queryClientes = from cli in clientes
select cli;
Filtragem:
var queryClientes = from cli in clientes
where cli.Saldo < 0
select cli;
...
var queryClientes = from cli in clientes
where cli.Saldo < 0 && cli.Idade < 26
select cli;
Operações de Consulta 2
Ordenação:
var queryClientes = from cli in clientes
where cli.Saldo < 0 && cli.Idade < 26
orderby cli.Cidade
select cli;
Agrupamento:
var queryClientes = from cli in clientes
group cli by cli.Cidade;
Aqui, queryClientes é do tipo
IEnumerable<IGrouping<string, Cliente>>
Operações de Consulta 3
Agrupamento (cont.):
//...
foreach (var groupClientes in queryClientes)
{
Console.WriteLine(groupClientes.Key);
foreach (Cliente cliente in groupClientes)
{
Console.WriteLine("--- {0}", cliente.Nome);
}
} Aqui, groupClientes é do tipo
IGouping<string, Cliente>
Operações de Consulta 4
Agrupamento 2:
var queryClientes =
from cli in clientes
group cli by cli.Cidade into cliGroup
where cliGroup.Count() > 2
orderby cliGroup.Key
select cliGroup;
Transformação de dados
Subsetting:
var queryClientes =
from cli in clientes
select new {
NomeCliente = cli.Nome,
Area = cli.Area
};
foreach (var cli in queryClientes)
{
Console.WriteLine(cli.NomeCliente + ", " + cli.Area);
}
Tipo Anônimo
Transformação de dados 2
Junção:
var juncaoClienteVendedor =
from cli in clientes
join vend in vendedores on cli.Area equals vend.Area
select new { NomeCliente = cli.Nome, NomeVendedor =
vend.Nome };
Transformação de dados 3
Criação de XML:
var studentsToXML =
new XElement("Root",
from student in students
let x = String.Format(
"{0},{1},{2},{3}",
student.Scores[0],
student.Scores[1],
student.Scores[2],
student.Scores[3])
select new XElement("student",
new XElement("First", student.First),
new XElement("Last", student.Last),
new XElement("Scores", x)));
Transformação de dados 4
Criação de XML(cont.) - Resultado :
<Root>
<student>
<First>Svetlana</First>
<Last>Omelchenko</Last>
<Scores>97,92,81,60</Scores>
</student>
<student>
<First>Claire</First>
<Last>O'Donnell</Last>
<Scores>75,84,91,39</Scores>
</student>
<student>
<First>Sven</First>
<Last>Mortensen</Last>
<Scores>88,94,65,91</Scores>
</student>
</Root>
Providers e API's
- LINQ To Objects
- LINQ To XML
- LINQ To SQL
- LINQ To Datasets
- LINQ To Entities
- LINQ To Google Search
- LINQ To Twitter
- LINQ To Wikipedia
- LINQ To NHibernate
- LINQ To Windos Search
...
Estendendo LINQ
Dados em memória:
- implementar IEnumerable<T>
Dados remotos:
- implementar IQueryable<T>
Criando um Provider remoto:
- implementação requerida: IQueryable<T>,
IOrderedQueryable<T> e IQueryProvider
* cuidado com performance na implementação!
Referências
Portal do LINQ no MSDN: http://bit.ly/11X5kXz
Artigo na Wikipedia: http://bit.ly/18MpCF
LINQ To Entities: http://bit.ly/13w0fqW
LINQ To Google: http://glinq.codeplex.com/
LINQ To Windos Search: http://bit.ly/117CLCW
LINQ To Twitter: http://bit.ly/dzrHjQ
Referências 2
Lambda Calculus: http://bit.ly/3LBzDJ
Lambda no C#: http://bit.ly/SakjXd
Extension Methods: http://bit.ly/SakjXd
Tipos anônimos: http://bit.ly/10ntsDI
Inferência de tipo: http://bit.ly/6puEY4
Perguntas?
Obrigado!

LINQ - C#

  • 1.
  • 2.
    Facilitador Fernando Padoan Engenheiro deSistemas http://www.cesar.org.br/
  • 3.
    O que éo LINQ "Language Integrated Query" Adicionado ao .Net em 2007 Permite criar consultas a dados utilizando as linguagens suportadas pelo .Net Framework Inspirado em SQL e Haskell
  • 4.
    Exemplo de Consulta string[]linguagens = new string[5] { "C#", "VB", "Javascript", "C++", "F#" }; var nomesCurtos = from li in linguagens where li.Length < 4 select li; foreach (string nome in nomesCurtos) { Console.WriteLine(nome); } C# VB C++ F#
  • 5.
    Data Source string[] linguagens= new string[5] { "C#", "VB", "Javascript", "C++", "F#" }; Array IEnumerable<T> apenas em runtime
  • 6.
    Query var nomesCurtos = fromli in linguagens where li.Length < 4 select li; inferência de tipo fonte dos dados filtragem tipo do retorno Até este momento, a consulta não é executada, e nenhum dado é retornado!
  • 7.
    Deferred Execution foreach (stringnome in nomesCurtos) { Console.WriteLine(nome); } Execução da consulta ocorre ao iterar pelo objeto de consulta em um foreach.
  • 8.
    Execução Imediata int quantos= nomesCurtos.Count(); Outros exemplos: .ToArray(), .ToList(), .First()...
  • 9.
    Tipos de Dados "Queryabledata types": IEnumerable IEnumerable<T> IQueryable<T> ... ou qualquer outro tipo que implemente IEnumerable<T>.
  • 10.
    Tipos de Dadosna Consulta IEnumerable<string> nomesCurtos = from li in linguagens where li.Length < 4 select li; Mais exemplos:
  • 11.
    Query vs. MethodSyntax int[] numeros = { 1, 2, 3, 5, 8, 13, 21, 34 }; IEnumerable<int> pares = // query??? foreach (int i in pares) { Console.Write(i + " "); }
  • 12.
    Query Syntax IEnumerable<int> pares= from num in numeros where num % 2 == 0 orderby num select num;
  • 13.
    Method Syntax IEnumerable<int> pares= numeros.Where(num => num % 2 == 0).OrderBy(n => n); Extension methods Lambda expressions
  • 14.
    LINQ Extension Methods namespaceSystem.Linq { public static class Enumerable { // ... public static IEnumerable<TSource> Where<TSource>( this IEnumerable<TSource> source, Func<TSource, bool> predicate) // ... } // ... }
  • 15.
    Lambda Expressions "num =>num % 2 == 0" "n => n" "Func<TSource, bool> predicate" "=>" : "goes to"
  • 16.
    Operações de Consulta Obtençãode dados: var queryClientes = from cli in clientes select cli; Filtragem: var queryClientes = from cli in clientes where cli.Saldo < 0 select cli; ... var queryClientes = from cli in clientes where cli.Saldo < 0 && cli.Idade < 26 select cli;
  • 17.
    Operações de Consulta2 Ordenação: var queryClientes = from cli in clientes where cli.Saldo < 0 && cli.Idade < 26 orderby cli.Cidade select cli; Agrupamento: var queryClientes = from cli in clientes group cli by cli.Cidade; Aqui, queryClientes é do tipo IEnumerable<IGrouping<string, Cliente>>
  • 18.
    Operações de Consulta3 Agrupamento (cont.): //... foreach (var groupClientes in queryClientes) { Console.WriteLine(groupClientes.Key); foreach (Cliente cliente in groupClientes) { Console.WriteLine("--- {0}", cliente.Nome); } } Aqui, groupClientes é do tipo IGouping<string, Cliente>
  • 19.
    Operações de Consulta4 Agrupamento 2: var queryClientes = from cli in clientes group cli by cli.Cidade into cliGroup where cliGroup.Count() > 2 orderby cliGroup.Key select cliGroup;
  • 20.
    Transformação de dados Subsetting: varqueryClientes = from cli in clientes select new { NomeCliente = cli.Nome, Area = cli.Area }; foreach (var cli in queryClientes) { Console.WriteLine(cli.NomeCliente + ", " + cli.Area); } Tipo Anônimo
  • 21.
    Transformação de dados2 Junção: var juncaoClienteVendedor = from cli in clientes join vend in vendedores on cli.Area equals vend.Area select new { NomeCliente = cli.Nome, NomeVendedor = vend.Nome };
  • 22.
    Transformação de dados3 Criação de XML: var studentsToXML = new XElement("Root", from student in students let x = String.Format( "{0},{1},{2},{3}", student.Scores[0], student.Scores[1], student.Scores[2], student.Scores[3]) select new XElement("student", new XElement("First", student.First), new XElement("Last", student.Last), new XElement("Scores", x)));
  • 23.
    Transformação de dados4 Criação de XML(cont.) - Resultado : <Root> <student> <First>Svetlana</First> <Last>Omelchenko</Last> <Scores>97,92,81,60</Scores> </student> <student> <First>Claire</First> <Last>O'Donnell</Last> <Scores>75,84,91,39</Scores> </student> <student> <First>Sven</First> <Last>Mortensen</Last> <Scores>88,94,65,91</Scores> </student> </Root>
  • 24.
    Providers e API's -LINQ To Objects - LINQ To XML - LINQ To SQL - LINQ To Datasets - LINQ To Entities - LINQ To Google Search - LINQ To Twitter - LINQ To Wikipedia - LINQ To NHibernate - LINQ To Windos Search ...
  • 25.
    Estendendo LINQ Dados emmemória: - implementar IEnumerable<T> Dados remotos: - implementar IQueryable<T> Criando um Provider remoto: - implementação requerida: IQueryable<T>, IOrderedQueryable<T> e IQueryProvider * cuidado com performance na implementação!
  • 26.
    Referências Portal do LINQno MSDN: http://bit.ly/11X5kXz Artigo na Wikipedia: http://bit.ly/18MpCF LINQ To Entities: http://bit.ly/13w0fqW LINQ To Google: http://glinq.codeplex.com/ LINQ To Windos Search: http://bit.ly/117CLCW LINQ To Twitter: http://bit.ly/dzrHjQ
  • 27.
    Referências 2 Lambda Calculus:http://bit.ly/3LBzDJ Lambda no C#: http://bit.ly/SakjXd Extension Methods: http://bit.ly/SakjXd Tipos anônimos: http://bit.ly/10ntsDI Inferência de tipo: http://bit.ly/6puEY4
  • 28.
  • 29.