Uma junção cruzada, também conhecida como um produto cartesiano, junta duas sequências de valores para criar uma nova coleção em que cada par combinado possível é representado. Ao usar a Language-Integrated Query (LINQ), a junção cruzada pode substituir loops aninhados. |
A LINQ suporta dois tipos de junção principais :
Outro tipo de junção suporta pela LINQ é a junção cruzada (cross join) ou Produto Cartesiano. Neste caso ao combinar duas sequências usando esta abordagem cada item na primeira coleção é combinado com cada item na segunda coleção.
Nenhuma chave de seleção é requerida pois não há nenhuma filtragem de dados. A sequência resultante terá sempre o número de itens igual ao produto dos tamanhos das duas sequências originais.
Vamos mostrar neste artigo como realizar junções cruzadas com LINQ.
Recursos usados:
Nota: Baixe e use a versão Community 2015 do VS ela é grátis e é equivalente a versão Professional.
Abra o VS Community 2015 e clique em New Project;
Selecione a Other Projects Type -> Visual Studio Solution e marque Blank Solution;
No menu File clique em Add -> New Project e inclua um projeto usando a linguagem C# e outro usando a linguagem VB .NET do tipo Console Application.
Assim teremos dois projetos onde iremos definir o código da nossa consulta de junção cruzada.
Executar
uma junção cruzada com sintaxe de expressão de consulta do
LINQ é simplesmente um caso de incluir duas cláusulas from : uma
para cada sequência fonte. Em seguida, adicionamos uma projeção usando a
palavra-chave select. O código permanece conciso, enquanto que a intenção
é muito clara, dando boa legibilidade e facilidade de manutenção.
O exemplo a seguir demonstra uma consulta de junção cruzada onde temos temos
oito letras, que representam as colunas de um tabuleiro de xadrez. A segunda
coleção tem oito dígitos para linhas tabuleiro.
Quando combinamos as duas sequências usando uma junção cruzada, geramos sessenta e quatro coordenadas; um para cada um dos quadrados do tabuleiro de xadrez.
O código VB .NET e CSharp definido em uma aplicação do tipo Console Application é mostrado abaixo:
Module Module1
Sub Main()
Dim letras As Char() = "ABCDEFGH".ToCharArray()
Dim digitos As Char() = "12345678".ToCharArray()
Dim coordenadas = From l In letras
From d In digitos
Select l.ToString() + d
For Each coord In coordenadas
Console.Write("{0} ", coord)
If coord.EndsWith("8") Then
Console.WriteLine()
End If
Next
Console.ReadKey()
End Sub
End Module
|
using System;
using System.Linq;
namespace CSharp_LINQ_juncao_cruzada
{
class Program
{
static void Main(string[] args)
{
char[] letras = "ABCDEFGH".ToCharArray();
char[] digitos = "12345678".ToCharArray();
var coordenadas =
from l in letras
from d in digitos
select l.ToString() + d;
foreach (var coord in coordendas)
{
Console.Write("{0} ", coord);
if (coord.EndsWith("8"))
{
Console.WriteLine();
}
}
}
}
}
|
VB .NET | CSharp |
O resultado obtido é mostrado a seguir:
Você pode notar pelo resultado que a primeira sequência da consulta é executada uma vez, ao passo que a segunda sequência, contendo os dígitos, é repetida para cada letra. É importante perceber que a segunda sequência será enumerada uma vez para cada item da primeira sequência.
Usando os operadores de consulta padrão
Para alcançar os mesmos resultados usando os operadores de consulta padrão podemos usar o operador SelectMany. Normalmente usaríamos esse método de extensão para realizar uma projeção um-para-muitos para uma sequência plana.
O método SelectMany -
Projeta cada elemento de uma sequência a
IEnumerable(Of T) e mesclar as sequências
resultantes em uma sequência.
|
Por exemplo, você pode ter uma coleção de membros de uma equipe, com cada objeto na seqüência contendo uma lista de habilidades que cada pessoa possui. Com SelectMany, você poderia criar uma nova seqüência contendo as habilidades combinadas de todos os membros da equipe.
Para realizar a junção cruzada usaríamos o operador SelectMany contra a primeira sequência, e, onde normalmente, você usaria uma expressão lambda para especificar qual itens filhos retornar, você fornece uma expressão lambda que seleciona os itens da segunda sequência. Isso significa que todos os itens na segunda coleção são selecionados uma vez para cada item na primeira sequência.
A linha de código a seguir produz o mesmo resultado obtido no exemplo do tabuleiro de xadrez. A primeira expressão lambda obtêm os dígitos uma vez para cada letra e a segunda função combina a letra e o digito para cada um dos 64 resultados.
VB .NET |
var coordenadas = letras.SelectMany(l => digitos, (l, d) => l.ToString() + d);
|
CSharp |
Dim coordenadas = letras.SelectMany(Function(l) digitos, Function(l, d) l.ToString() + d)
|
Apenas para constar, a seguir temos um trecho de código que usa laços foreach aninhados para obter o mesmo resultado sem utilizar uma consulta LINQ :
List<string> coordenadas = new List<string>();
foreach (char letra in letras)
{
foreach (char digito in digitos)
{
coordenadas.Add(letra.ToString() + digito);
}
}
|
Dim coordenadas As New List(Of String)()
For Each letra As Char In letras
For Each digito As Char In digitos
coordenadas.Add(letra.ToString() + digito)
Next
Next
|
Pegue o projeto completo aqui : LINQ_juncao_cruzada.zip
Deus nunca foi visto por alguém. O Filho
unigênito (Jesus), que está no seio do Pai, esse o revelou.
João 1:18
Veja os
Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique
e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
Quer aprender os conceitos da Programação Orientada a objetos ? Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ? Quer aprender a criar aplicações Web Dinâmicas usando a ASP .NET MVC 5 ? |
Gostou ? Compartilhe no Facebook Compartilhe no Twitter
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
LINQ - Usando os operadores SKIP, TAKE e LET - Macoratti ...