Junção interna do LINQ

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 Productclasse que tenha três propriedades Id,, Namee 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 Itemclasse que possui três propriedades ProductId,, Qtye 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 ProductIdda Itemclasse corresponde ao Idda Productclasse.

Terceiro, crie uma lista de três Productobjetos no Main()método da Programclasse:

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:

  • ProductIdna Itemlista items.
  • Idna Productlista products.

O resultado da junção interna é uma nova sequência de objetos anônimos. Cada objeto contém os dados de correspondência Iteme Productobjetos em ambas as sequências.

O Join()método leva quatro argumentos:

  1. O primeiro argumento é a lista de produtos que é a sequência a ser associada.
  2. O segundo argumento é uma expressão lambda que define a propriedade correspondente na lista de itens – item=> item.ProductId.
  3. O terceiro argumento é uma expressão lambda que define a propriedade correspondente na lista de produtos – product => product.Id.
  4. 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.PriceQtyMarginMargin

Por fim, exiba o resultado da junção no console usando um foreachloop 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 candidatese employeescom 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/2010Linguagem de código:  C#  ( cs )

Neste exemplo:

Primeiro, defina duas classes: Candidatee Employee.

Segundo, crie duas listas de candidatos e funcionários que contenham os objetos Candidatee Employeerespectivamente.

Terceiro, junte as duas listas com base na correspondência das propriedades FirstNamee LastName. O Join()método é chamado na candidateslista e recebe quatro argumentos:

  • O employeespara se juntar.
  • Uma expressão lambda que seleciona a chave do Candidateobjeto a ser unida ( FirstNamee LastName)
  • Uma expressão lambda que seleciona a chave do Employeeobjeto a ser unida ( FirstNamee LastName).
  • 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, InterviewDatee JoinedDate.

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.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *