Resumo : neste tutorial, você aprenderá como usar o Join()
método LINQ para realizar uma junção interna de duas sequências com base em uma ou mais chaves.
Introdução à junção interna do LINQ
Para unir duas sequências com base em uma ou mais chaves, você usa o Join()
método de extensão LINQ. Aqui está a sintaxe do Join()
método:
public static IEnumerable<TResult> Join<TOuter,TInner,TKey,TResult> (
this IEnumerable<TOuter> outer,
IEnumerable<TInner> inner,
Func<TOuter,TKey> outerKeySelector,
Func<TInner,TKey> innerKeySelector,
Func<TOuter,TInner,TResult> resultSelector
);
Linguagem de código: C# ( cs )
Nesta sintaxe:
outer
é a primeira sequência a ingressar.inner
é a sequência que se une à primeira sequência.outerKeySelector
é uma função que extrai a chave de junção de cada elemento da primeira sequência.innerKeySelector
é uma função que extrai a chave de junção de cada elemento da segunda sequência.resultSelector
é uma função que cria o elemento de resultado a partir de dois elementos correspondentes.
O Join()
método retorna um IEnumerable<TResult>
que possui elementos como resultado de uma junção interna nas duas sequências.
Exemplos de junção interna do LINQ
Vejamos alguns exemplos de uso do Join()
método LINQ para realizar uma junção interna.
1) Usando o método LINQ Join() para realizar uma junção interna com base em uma única chave
O programa a seguir demonstra como usar o Join()
método para unir a lista de produtos à lista de itens com base no ID do produto:
class Product
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Cost { get; set; }
public Product(int id, string name, decimal cost)
{
Id = id;
Name = name;
Cost = cost;
}
}
class Item
{
public int ProductId { get; set; }
public int Qty { get; set; }
public decimal Price { get; set; }
public Item(int productId, int qty, decimal price)
{
ProductId = productId;
Qty = qty;
Price = price;
}
}
class Program
{
public static void Main(string[] args)
{
var products = new List<Product>()
{
new (id: 1, name: "A", cost: 10),
new (id: 2, name: "B", cost: 20),
new (id: 3, name: "C", cost: 30)
};
var items = new List<Item>()
{
new (productId:1, qty: 2, price: 12),
new (productId:2, qty: 2, price: 25),
new (productId:3, qty: 4, price: 35)
};
var results = items.Join(
products,
item => item.ProductId,
product => product.Id,
(item, product) => new
{
product.Name,
product.Cost,
item.Price,
item.Qty,
Margin = (item.Price - product.Cost) * item.Qty
}
);
foreach (var result in results)
{
Console.WriteLine(result);
}
}
}
Linguagem de código: C# ( cs )
Como funciona.
Primeiro, defina uma Product
classe que tenha três propriedades Id
,, Name
e Cost
.
class Product
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Cost { get; set; }
public Product(int id, string name, decimal cost)
{
Id = id;
Name = name;
Cost = cost;
}
}
Linguagem de código: C# ( cs )
Segundo, defina a Item
classe que possui três propriedades ProductId
,, Qty
e Price
:
class Item
{
public int ProductId { get; set; }
public int Qty { get; set; }
public decimal Price { get; set; }
public Item(int productId, int qty, decimal price)
{
ProductId = productId;
Qty = qty;
Price = price;
}
}
Linguagem de código: C# ( cs )
O ProductId
da Item
classe corresponde ao Id
da Product
classe.
Terceiro, crie uma lista de três Product
objetos no Main()
método da Program
classe:
var products = new List<Product>()
{
new (id: 1, name: "A", cost: 10),
new (id: 2, name: "B", cost: 20),
new (id: 3, name: "C", cost: 30)
};
Linguagem de código: C# ( cs )
Quarto, crie uma lista de três itens:
var items = new List<Item>()
{
new (productId:1, qty: 2, price: 12),
new (productId:2, qty: 2, price: 25),
new (productId:3, qty: 4, price: 35)
};
Linguagem de código: C# ( cs )
Quinto, junte a lista de produtos com a lista de itens com base no ID do produto:
var results = items.Join(
products,
item => item.ProductId,
product => product.Id,
(item, product) => new
{
product.Name,
product.Cost,
item.Price,
item.Qty,
Margin = (item.Price - product.Cost) * item.Qty
}
);
Linguagem de código: C# ( cs )
O Join()
método une a lista de produtos e itens com base na propriedade comum:
ProductId
naItem
listaitems
.Id
naProduct
listaproducts
.
O resultado da junção interna é uma nova sequência de objetos anônimos. Cada objeto contém os dados de correspondência Item
e Product
objetos em ambas as sequências.
O Join()
método leva quatro argumentos:
- O primeiro argumento é a lista de produtos que é a sequência a ser associada.
- O segundo argumento é uma expressão lambda que define a propriedade correspondente na lista de itens –
item=> item.ProductId
. - O terceiro argumento é uma expressão lambda que define a propriedade correspondente na lista de produtos –
product => product.Id
. - O quarto argumento é uma expressão lambda que define a forma dos objetos de resultado. Cada objeto anônimo possui quatro propriedades: ,
Name
,Cost
, e . A propriedade representa a margem de lucro de cada item com base no custo do produto e no preço do item.Price
Qty
Margin
Margin
Por fim, exiba o resultado da junção no console usando um foreach
loop e WriteLine()
um método.
O seguinte mostra a sintaxe da consulta que é equivalente à sintaxe do método acima:
var results = from product in products
join item in items on product.Id equals item.ProductId
select new
{
product.Name,
product.Cost,
item.Price,
item.Qty,
Margin = (item.Price - product.Cost) * item.Qty
};
Linguagem de código: C# ( cs )
2) Usando o método LINQ Join() para realizar uma junção interna com base em uma chave composta
O programa a seguir demonstra como usar o Join()
método para unir as listas candidates
e employees
com base no nome e no sobrenome:
class Candidate
{
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime InterviewDate { get; set; }
public Candidate(string firstName, string lastName, DateTime interviewDate)
{
FirstName = firstName;
LastName = lastName;
InterviewDate = interviewDate;
}
}
class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime JoinedDate { get; set; }
public Employee(string firstName, string lastName, DateTime joinedDate)
{
FirstName = firstName;
LastName = lastName;
JoinedDate = joinedDate;
}
}
class Program
{
static void Main(string[] args)
{
// Create a list of candidates
List<Candidate> candidates = new()
{
new ("John", "Doe", new DateTime(2010, 1, 20)),
new ("Jane", "Doe", new DateTime(2010, 1, 28)),
new ("Bob", "Smith",new DateTime(2010, 1, 15))
};
// Create a list of employees
List<Employee> employees = new()
{
new ("John", "Doe", new DateTime(2010, 2, 1)),
new ("Jane", "Doe", new DateTime(2010, 2, 2)),
new ("Alice", "Johnson", new DateTime(2010, 2, 3))
};
var query = candidates.Join(
employees,
candidate => new { candidate.FirstName, candidate.LastName },
employee => new { employee.FirstName, employee.LastName },
(candidate, employee) => new
{
Name = $"{candidate.FirstName} {candidate.LastName}",
candidate.InterviewDate,
employee.JoinedDate
});
foreach (var result in query)
{
Console.WriteLine($"{result.Name} was interviewd on {result.InterviewDate.ToShortDateString()} and joined on {result.JoinedDate.ToShortDateString()}");
}
}
}
Linguagem de código: C# ( cs )
Saída:
John Doe was interviewd on 1/20/2010 and joined on 2/1/2010
Jane Doe was interviewd on 1/28/2010 and joined on 2/2/2010
Linguagem de código: C# ( cs )
Neste exemplo:
Primeiro, defina duas classes: Candidate
e Employee
.
Segundo, crie duas listas de candidatos e funcionários que contenham os objetos Candidate
e Employee
respectivamente.
Terceiro, junte as duas listas com base na correspondência das propriedades FirstName
e LastName
. O Join()
método é chamado na candidates
lista e recebe quatro argumentos:
- O
employees
para se juntar. - Uma expressão lambda que seleciona a chave do
Candidate
objeto a ser unida (FirstName
eLastName
) - Uma expressão lambda que seleciona a chave do
Employee
objeto a ser unida (FirstName
eLastName
). - Uma expressão lambda que cria um novo objeto anônimo para a lista de resultados. O objeto anônimo contém as propriedades
Name
,InterviewDate
eJoinedDate
.
Por fim, itere sobre o resultado e grave cada objeto no console.
O seguinte mostra a sintaxe da consulta que é equivalente à sintaxe do método acima:
var query = from candidate in candidates
join employee in employees
on new { candidate.FirstName, candidate.LastName }
equals new { employee.FirstName, employee.LastName }
select new
{
Name = $"{candidate.FirstName} {candidate.LastName}",
candidate.InterviewDate,
employee.JoinedDate
};
Linguagem de código: C# ( cs )
Resumo
- Use
Join()
o método LINQ para unir duas sequências com base em uma ou mais chaves.