Ich versuche, einen Join zwischen mehreren Tabellen in LINQ durchzuführen . Ich habe folgende Klassen:
Product {Id, ProdName, ProdQty}
Category {Id, CatName}
ProductCategory{ProdId, CatId} //association table
Und ich verwende den folgenden Code (wo product
, category
und productcategory
sind Instanzen der oben genannten Klassen):
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});
Mit diesem Code erhalte ich ein Objekt aus folgender Klasse:
QueryClass { productproductcategory, category}
Wo die Produktkategorie vom Typ ist:
ProductProductCategoryClass {product, productcategory}
Ich verstehe nicht, wo sich die verknüpfte "Tabelle" befindet. Ich habe eine einzelne Klasse erwartet , die alle Eigenschaften der beteiligten Klassen enthält.
Mein Ziel ist es, ein anderes Objekt mit einigen Eigenschaften zu füllen, die sich aus der Abfrage ergeben:
CategorizedProducts catProducts = query.Select(m => new { m.ProdId = ???, m.CatId = ???, //other assignments });
Wie kann ich dieses Ziel erreichen?
Antworten:
Für Joins bevorzuge ich nachdrücklich die Abfragesyntax für alle Details, die glücklich verborgen sind (nicht zuletzt die transparenten Bezeichner, die mit den Zwischenprojektionen auf dem Weg verbunden sind, die im Punktsyntaxäquivalent erkennbar sind). Sie haben jedoch nach Lambdas gefragt, von denen ich denke, dass Sie alles haben, was Sie brauchen - Sie müssen nur alles zusammenfügen.
Wenn nötig, können Sie den Join in einer lokalen Variablen speichern und später wiederverwenden. Da jedoch keine anderen Details vorliegen, sehe ich keinen Grund, die lokale Variable einzuführen.
Sie können das auch
Select
in das letzte Lambda des zweiten werfenJoin
(vorausgesetzt, es gibt keine anderen Operationen, die von den Verknüpfungsergebnissen abhängen), die Folgendes ergeben würden:... und wenn Sie einen letzten Versuch unternehmen, Ihnen die Abfragesyntax zu verkaufen, würde dies folgendermaßen aussehen:
Möglicherweise sind Ihnen die Hände gebunden, ob die Abfragesyntax verfügbar ist. Ich weiß, dass einige Geschäfte solche Mandate haben - oft basierend auf der Vorstellung, dass die Abfragesyntax etwas eingeschränkter ist als die Punktsyntax. Es gibt andere Gründe, wie "Warum sollte ich eine zweite Syntax lernen, wenn ich alles und mehr in Punktsyntax tun kann?" Wie dieser letzte Teil zeigt, gibt es Details, die die Abfragesyntax verbirgt und die es wert sind, mit der damit verbundenen Verbesserung der Lesbarkeit in Betracht gezogen zu werden: Alle Zwischenprojektionen und Bezeichner, die Sie erstellen müssen, sind glücklicherweise nicht frontal und zentriert. Stufe in der Abfragesyntaxversion - sie sind Hintergrundflusen. Jetzt aus meiner Seifenkiste - jedenfalls danke für die Frage. :) :)
quelle
JOIN
Anweisung benötigen ? Wie machen wir das? Zum Beispieljoin pc in productcategory on p.Id equals pc.ProdId
müssen wir in der Zeile hinzufügenand p.Id == 1
.p.Id == 1
da dies eher ein Where-Filter als ein Join-Kriterium ist. Die Art und Weise, wie Sie einen Join nach mehr als einem Kriterium durchführen, besteht im Allgemeinen darin, einen anonymen Typ zu verwenden :join pc in productcategory on new { Id = p.Id, Other = p.Other } equals new { Id = pc.ProdId, Other = pc.Other }
. Dies funktioniert in Linq-to-Objects, und ich gehe davon aus, dass dies auch bei Datenbankabfragen funktioniert. Mit Datenbanken können Sie möglicherweise auf komplizierte Join-Abfragen verzichten, indem Sie Fremdschlüssel als geeignet definieren und über die zugehörige Eigenschaft auf verwandte Daten zugreifen.Was Sie gesehen haben, ist das, was Sie bekommen - und genau darum haben Sie hier gebeten:
Dies ist ein Lambda-Ausdruck, der einen anonymen Typ mit diesen beiden Eigenschaften zurückgibt.
In Ihren CategorizedProducts müssen Sie nur die folgenden Eigenschaften verwenden:
quelle
CatId
funktioniert einwandfrei. DennProdId
es solltem.productproductcategory.product.Id
ODER seinm.productproductcategory.productcategory.ProdId
. Die beiden Zuordnungen unterscheiden sich, die erste bezieht sich auf das Produkt (verbunden mitproductcategory
), die zweite aufproductcategory
verbunden mit beidenproduct
undcategory
. Folgen Sie meiner Argumentation?Schauen Sie sich diesen Beispielcode aus meinem Projekt an
In diesem Code habe ich 3 Tabellen verbunden und die Join-Bedingung aus der where-Klausel ausgespuckt
Hinweis: Die Services-Klassen werden nur die Datenbankoperationen verzerrt (gekapselt)
quelle
quelle
quelle
Es ist eine Weile her, aber meine Antwort kann jemandem helfen:
Wenn Sie die Beziehung bereits richtig definiert haben, können Sie Folgendes verwenden:
quelle