Preciso fazer uma consulta LINQ2DataSet que faça uma junção em mais de um campo (como
var result = from x in entity
join y in entity2
on x.field1 = y.field1
and
x.field2 = y.field2
Eu ainda encontrei uma solução adequada (posso adicionar restrições adicionais a uma cláusula where, mas isso está longe de ser uma solução adequada ou usar essa solução, mas isso pressupõe um equijoin).
É possível no LINQ ingressar em vários campos em uma única associação?
EDITAR
var result = from x in entity
join y in entity2
on new { x.field1, x.field2 } equals new { y.field1, y.field2 }
é a solução que referi como assumindo um equijoin acima.
EDIT adicional
Para responder às críticas de que meu exemplo original era um equijoin, reconheço que, meu requisito atual é para um equijoin e já empreguei a solução a que me referi acima.
No entanto, estou tentando entender quais possibilidades e melhores práticas eu tenho / devo empregar com o LINQ. Vou precisar fazer uma junção de consulta de intervalo de datas com um ID de tabela em breve e estava antecipando esse problema. Parece que terei que adicionar o período na cláusula where.
Obrigado, como sempre, por todas as sugestões e comentários fornecidos
Respostas:
A solução com o tipo anônimo deve funcionar bem. LINQ pode representar apenas equijoins (com cláusulas de junção, de qualquer maneira), e é isso que você disse que deseja expressar de qualquer maneira com base na sua consulta original.
Se você não gostar da versão com o tipo anônimo por algum motivo específico, explique esse motivo.
Se você quiser fazer algo diferente do que pediu originalmente, dê um exemplo do que você realmente deseja fazer.
EDIT: Respondendo à edição na pergunta: sim, para fazer uma junção de "período", você precisa usar uma cláusula where. Eles são semanticamente equivalentes, portanto, é apenas uma questão de otimizações disponíveis. Os equivalentes fornecem otimização simples (no LINQ to Objects, que inclui o LINQ to DataSets) criando uma pesquisa com base na sequência interna - pense nela como uma tabela de hash da chave para uma sequência de entradas correspondentes a essa chave.
Fazer isso com períodos é um pouco mais difícil. No entanto, dependendo exatamente do que você quer dizer com "ingresso no período", você poderá fazer algo semelhante - se estiver planejando criar "faixas" de datas (por exemplo, uma por ano), de modo que duas entradas que ocorram no o mesmo ano (mas não na mesma data) deve corresponder, então você pode fazê-lo usando essa banda como chave. Se for mais complicado, por exemplo, um lado da junção fornece um intervalo, e o outro lado da junção fornece uma única data, correspondente se estiver dentro desse intervalo, que seria melhor manipulada com uma
where
cláusula (após um segundofrom
cláusula) IMO. Você poderia fazer uma mágica particularmente descolada, ordenando de um lado ou de outro para encontrar correspondências com mais eficiência, mas isso daria muito trabalho - eu só faria esse tipo de coisa depois de verificar se o desempenho é um problema.fonte
fonte
on new { X1= x.field1, X2= x.field2 } equals new { X1=y.field1, X2= y.field2 }
trabalhou #Você precisa fazer isso, se os nomes das colunas forem diferentes em duas entidades.
fonte
Apenas para concluir isso com uma sintaxe de cadeia de método equivalente:
Enquanto o último argumento
(x, y) => x
é o que você seleciona (no caso acima, selecionamosx
).fonte
Eu acho que uma opção mais legível e flexível é usar a função Where:
Isso também permite alterar facilmente da junção interna para a esquerda adicionando .DefaultIfEmpty ().
fonte
{ ... } equals new { ... }
sintaxe. LinqPad é uma grande ferramenta para ver como expressões estão se comportando (script SQL se LINQ2SQL é usado, árvores de expressão etc.)fonte
você poderia fazer algo como (abaixo)
fonte
Usando o operador de junção, você só pode executar equijóins. Outros tipos de junções podem ser construídos usando outros operadores. Não tenho certeza se a junção exata que você está tentando fazer seria mais fácil usando esses métodos ou alterando a cláusula where. A documentação da cláusula de junção pode ser encontrada aqui . O MSDN também tem um artigo sobre operações de associação com vários links para exemplos de outras associações.
fonte
Se o nome do campo for diferente nas entidades
fonte
Como uma cadeia de métodos completa, seria assim:
fonte
isso funciona para mim
fonte
Declare uma Classe (Tipo) para conter os elementos que você deseja unir. No exemplo abaixo, declare JoinElement
fonte