Estou tentando realizar uma junção entre várias tabelas no LINQ. Tenho as seguintes aulas:
Product {Id, ProdName, ProdQty}
Category {Id, CatName}
ProductCategory{ProdId, CatId} //association table
E eu uso o seguinte código (onde product
, category
e productcategory
são instâncias das classes acima):
var query = product.Join(productcategory, p => p.Id, pc => pc.ProdID, (p, pc) => new {product = p, productcategory = pc})
.Join(category, ppc => ppc.productcategory.CatId, c => c.Id, (ppc, c) => new { productproductcategory = ppc, category = c});
Com este código, obtenho um objeto da seguinte classe:
QueryClass { productproductcategory, category}
Onde productproductcategory é do tipo:
ProductProductCategoryClass {product, productcategory}
Não entendo onde está a "tabela" associada, esperava uma única classe que contivesse todas as propriedades das classes envolvidas.
Meu objetivo é preencher outro objeto com algumas propriedades resultantes da consulta:
CategorizedProducts catProducts = query.Select(m => new { m.ProdId = ???, m.CatId = ???, //other assignments });
como posso atingir esse objetivo?
Respostas:
Para junções, eu prefiro fortemente a sintaxe de consulta para todos os detalhes que ficam ocultos (não menos importante dos quais são os identificadores transparentes envolvidos com as projeções intermediárias ao longo do caminho que são aparentes no equivalente de sintaxe de ponto). No entanto, você perguntou sobre Lambdas, eu acho que você tem tudo o que precisa - você só precisa colocar tudo junto.
Se necessário, você pode salvar a junção em uma variável local e reutilizá-la mais tarde; porém, na falta de outros detalhes ao contrário, não vejo razão para introduzir a variável local.
Além disso, você poderia lançar o
Select
no último lambda do segundoJoin
(novamente, desde que não haja outras operações que dependam dos resultados da junção) que daria:... e fazendo uma última tentativa de convencê-lo da sintaxe de consulta, ficaria assim:
Suas mãos podem estar atadas quanto à disponibilidade de sintaxe de consulta. Eu sei que algumas lojas têm tais mandatos - muitas vezes com base na noção de que a sintaxe de consulta é um pouco mais limitada do que a sintaxe de ponto. Existem outras razões, como "por que devo aprender uma segunda sintaxe se posso fazer tudo e muito mais na sintaxe de pontos?" Como mostra esta última parte - há detalhes que a sintaxe de consulta oculta que podem fazer valer a pena abraçar com a melhoria da legibilidade que ela traz: todas as projeções intermediárias e identificadores que você precisa preparar felizmente não são front-and-center- estágio na versão de sintaxe de consulta - eles são fluff de fundo. Fora da minha caixa de sabão agora - de qualquer forma, obrigado pela pergunta. :)
fonte
JOIN
instrução? Como fazemos isso? Por exemplo, najoin pc in productcategory on p.Id equals pc.ProdId
linha, precisamos adicionarand p.Id == 1
.p.Id == 1
pois isso é mais um filtro where do que um critério de junção. A maneira como você faria uma junção de mais de um critério geral é usar um tipo anônimo:join pc in productcategory on new { Id = p.Id, Other = p.Other } equals new { Id = pc.ProdId, Other = pc.Other }
. Isso funciona no Linq-to-Objects e presumo que o mesmo funcione com consultas de banco de dados também. Com os bancos de dados, você pode ignorar consultas complicadas de junção definindo chaves estrangeiras conforme apropriado e acessando dados relacionados por meio da propriedade relacionada.O que você viu é o que você obtém - e é exatamente o que você pediu, aqui:
Essa é uma expressão lambda que retorna um tipo anônimo com essas duas propriedades.
Em seus CategorizedProducts, você só precisa acessar essas propriedades:
fonte
CatId
obras bem. PoisProdId
deve serm.productproductcategory.product.Id
ORm.productproductcategory.productcategory.ProdId
. As duas atribuições são diferentes, a primeira está no produto (unido comproductcategory
) e a segunda está comproductcategory
unido com ambosproduct
ecategory
. Você segue meu raciocínio?dê uma olhada neste código de amostra do meu projeto
neste código juntei 3 tabelas e coloquei a condição de junção da cláusula where
nota: as classes de serviços são apenas distorcidas (encapsulam) as operações do banco de dados
fonte
fonte
fonte
já faz um tempo, mas minha resposta pode ajudar alguém:
se você já definiu a relação corretamente, você pode usar isto:
fonte