J'essaye d'effectuer une jointure entre plusieurs tables dans LINQ. J'ai les classes suivantes:
Product {Id, ProdName, ProdQty}
Category {Id, CatName}
ProductCategory{ProdId, CatId} //association table
Et j'utilise le code suivant (où product
, category
et productcategory
sont des instances des classes ci-dessus):
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});
Avec ce code, j'obtiens un objet de la classe suivante:
QueryClass { productproductcategory, category}
Où la catégorie de produits est de type:
ProductProductCategoryClass {product, productcategory}
Je ne comprends pas où se trouve la "table" jointe, je m'attendais à une seule classe contenant toutes les propriétés des classes impliquées.
Mon objectif est de remplir un autre objet avec certaines propriétés résultant de la requête:
CategorizedProducts catProducts = query.Select(m => new { m.ProdId = ???, m.CatId = ???, //other assignments });
comment puis-je atteindre cet objectif?
Réponses:
Pour les jointures, je préfère fortement la syntaxe de requête pour tous les détails qui sont heureusement cachés (dont les identifiants transparents impliqués dans les projections intermédiaires en cours de route qui sont apparents dans l'équivalent de syntaxe de point). Cependant, vous avez demandé à propos de Lambdas que je pense que vous avez tout ce dont vous avez besoin - il vous suffit de tout mettre ensemble.
Si vous en avez besoin, vous pouvez enregistrer la jointure dans une variable locale et la réutiliser plus tard, mais en l'absence d'autres détails au contraire, je ne vois aucune raison d'introduire la variable locale.
De plus, vous pouvez lancer le
Select
dans le dernier lambda de la secondeJoin
(encore une fois, à condition qu'il n'y ait pas d'autres opérations qui dépendent des résultats de la jointure) ce qui donnerait:... et faire une dernière tentative pour vous vendre sur la syntaxe de requête, cela ressemblerait à ceci:
Vos mains peuvent être liées sur la disponibilité de la syntaxe de requête. Je sais que certains magasins ont de tels mandats - souvent basés sur la notion que la syntaxe de requête est un peu plus limitée que la syntaxe à points. Il y a d'autres raisons, comme "pourquoi devrais-je apprendre une deuxième syntaxe si je peux tout faire et plus en syntaxe à points?" Comme le montre cette dernière partie - il y a des détails que la syntaxe de requête cache qui peuvent valoir la peine d'être embrassés avec l'amélioration de la lisibilité qu'elle apporte: toutes ces projections et identificateurs intermédiaires que vous devez préparer ne sont heureusement pas au centre. étape dans la version de syntaxe de requête - ce sont des peluches d'arrière-plan. De ma boîte à savon maintenant - de toute façon, merci pour la question. :)
la source
JOIN
instruction? Comment fait-on cela? Par exemple, dans lajoin pc in productcategory on p.Id equals pc.ProdId
ligne, nous devons ajouterand p.Id == 1
.p.Id == 1
car il s'agit plus d'un filtre where que d'un critère de jointure. La façon dont vous feriez une jointure sur plus d'un critère est généralement d'utiliser un type anonyme:join pc in productcategory on new { Id = p.Id, Other = p.Other } equals new { Id = pc.ProdId, Other = pc.Other }
. Cela fonctionne dans Linq-to-Objects, et je suppose que cela fonctionnera également avec les requêtes de base de données. Avec les bases de données, vous pouvez éviter les requêtes de jointure compliquées en définissant des clés étrangères comme il convient et en accédant aux données associées via la propriété associée.Ce que vous avez vu est ce que vous obtenez - et c'est exactement ce que vous avez demandé, ici:
C'est une expression lambda renvoyant un type anonyme avec ces deux propriétés.
Dans vos produits classés, il vous suffit de passer par ces propriétés:
la source
CatId
travaux très bien. CarProdId
cela devrait êtrem.productproductcategory.product.Id
OUm.productproductcategory.productcategory.ProdId
. Les deux affectations diffèrent, la première est sur le produit (joint avecproductcategory
), la seconde est avecproductcategory
joint avec les deuxproduct
etcategory
. Suivez-vous mon raisonnement?jetez un œil à cet exemple de code de mon projet
dans ce code, j'ai rejoint 3 tables et j'ai craché la condition de jointure à partir de la clause where
note: les classes Services sont juste déformées (encapsulent) les opérations de la base de données
la source
la source
la source
cela fait un moment mais ma réponse peut aider quelqu'un:
si vous avez déjà défini correctement la relation, vous pouvez utiliser ceci:
la source