Vorgehensweise Join zwischen mehreren Tabellen in LINQ Lambda

Ich versuche, eine Verknüpfung zwischen mehreren Tabellen in LINQ durchzuführen. Ich habe folgende classn:

Product {Id, ProdName, ProdQty} Category {Id, CatName} ProductCategory{ProdId, CatId} //association table 

Und ich verwende den folgenden Code (wobei product , category und productcategory Instanzen der obigen classn sind):

 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 der folgenden class:

 QueryClass { productproductcategory, category} 

Wo Produktkategorie ist:

 ProductProductCategoryClass {product, productcategory} 

Ich verstehe nicht, wo die verbundene “Tabelle” ist, ich erwartete eine einzelne class , die alle Eigenschaften der beteiligten classn enthält.

Mein Ziel ist es, ein anderes Objekt mit einigen Eigenschaften aus der Abfrage zu füllen:

 CategorizedProducts catProducts = query.Select(m => new { m.ProdId = ???, m.CatId = ???, //other assignments }); 

Wie kann ich dieses Ziel erreichen?

    Bei Joins bevorzuge ich die Abfragesyntax für alle Details, die glücklich versteckt sind (nicht zuletzt die transparenten Identifikatoren, die bei den Zwischenprojektionen entlang des Weges involviert sind, die im Dot-Syntax-Äquivalent sichtbar sind). Sie haben jedoch nach Lambdas gefragt, von denen ich denke, dass Sie alles haben, was Sie brauchen – Sie müssen nur alles zusammensetzen.

     var categorizedProducts = product .Join(productcategory, p => p.Id, pc => pc.ProdId, (p, pc) => new { p, pc }) .Join(category, ppc => ppc.pc.CatId, c => c.Id, (ppc, c) => new { ppc, c }) .Select(m => new { ProdId = m.ppc.p.Id, // or m.ppc.pc.ProdId CatId = mcCatId // other assignments }); 

    Wenn Sie möchten, können Sie den Join in einer lokalen Variablen speichern und später wiederverwenden. Wenn jedoch keine anderen Details vorliegen, sehe ich keinen Grund, die lokale Variable einzuführen.

    Außerdem könnten Sie die Select in das letzte Lambda des zweiten Join (wiederum vorausgesetzt, es gibt keine anderen Operationen, die von den Join-Ergebnissen abhängen) casting, was Folgendes ergeben würde:

     var categorizedProducts = product .Join(productcategory, p => p.Id, pc => pc.ProdId, (p, pc) => new { p, pc }) .Join(category, ppc => ppc.pc.CatId, c => c.Id, (ppc, c) => new { ProdId = ppc.p.Id, // or ppc.pc.ProdId CatId = c.CatId // other assignments }); 

    … und einen letzten Versuch zu machen, Sie mit der Abfragesyntax zu verkaufen, würde dies so aussehen:

     var categorizedProducts = from p in product join pc in productcategory on p.Id equals pc.ProdId join c in category on pc.CatId equals c.Id select new { ProdId = p.Id, // or pc.ProdId CatId = c.CatId // other assignments }; 

    Ihre Hände können daran gebunden sein, ob eine Abfragesyntax verfügbar ist. Ich weiß, dass einige Geschäfte solche Mandate haben – oft auf der Grundlage, 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 Punkt-Syntax tun kann?” Wie dieser letzte Teil zeigt – gibt es Details, die die Abfragesyntax verbirgt, die es durchaus wert sind, sie mit der Verbesserung der Lesbarkeit zu verbinden: all jene Zwischenprojektionen und Identifikatoren, die Sie kochen müssen, sind glücklicherweise nicht Front-und-Center- Stufe in der Abfrage-Syntax-Version – sie sind Hintergrund Fluff. Aus meiner Seifenkiste jetzt – jedenfalls danke für die Frage. 🙂

    Was Sie gesehen haben, ist das, was Sie bekommen – und genau danach haben Sie gefragt:

     (ppc, c) => new { productproductcategory = ppc, category = c} 

    Das ist ein Lambda-Ausdruck, der einen anonymen Typ mit diesen beiden Eigenschaften zurückgibt.

    In Ihren kategorisierten Produkten müssen Sie nur über diese Eigenschaften gehen:

     CategorizedProducts catProducts = query.Select( m => new { ProdId = m.productproductcategory.product.Id, CatId = m.category.CatId, // other assignments }); 

    Schau dir diesen Beispielcode aus meinem Projekt an

     public static IList GetDepartmentLettersLinq(int departmentId) { IEnumerable allDepartmentLetters = from allLetter in LetterService.GetAllLetters() join allUser in UserService.GetAllUsers() on allLetter.EmployeeID equals allUser.ID into usersGroup from user in usersGroup.DefaultIfEmpty()// here is the tricky part join allDepartment in DepartmentService.GetAllDepartments() on user.DepartmentID equals allDepartment.ID where allDepartment.ID == departmentId select allLetter; return allDepartmentLetters.ToArray(); } 

    In diesem Code habe ich 3 Tabellen beigetreten und ich spuckte Join-Bedingung von Where-Klausel

    Hinweis: Die Services-classn sind nur verzogen (kapseln) die databaseoperationen

      public ActionResult Index() { List obj = new List(); var orderlist = (from a in db.OrderMasters join b in db.Customers on a.CustomerId equals b.Id join c in db.CustomerAddresses on b.Id equals c.CustomerId where a.Status == "Pending" select new { Customername = b.Customername, Phone = b.Phone, OrderId = a.OrderId, OrderDate = a.OrderDate, NoOfItems = a.NoOfItems, Order_amt = a.Order_amt, dis_amt = a.Dis_amt, net_amt = a.Net_amt, status=a.Status, address = c.address, City = c.City, State = c.State, Pin = c.Pin }) ; foreach (var item in orderlist) { CustomerOrder_Result clr = new CustomerOrder_Result(); clr.Customername=item.Customername; clr.Phone = item.Phone; clr.OrderId = item.OrderId; clr.OrderDate = item.OrderDate; clr.NoOfItems = item.NoOfItems; clr.Order_amt = item.Order_amt; clr.net_amt = item.net_amt; clr.address = item.address; clr.City = item.City; clr.State = item.State; clr.Pin = item.Pin; clr.status = item.status; obj.Add(clr); } 
     var query = from a in d.tbl_Usuarios from b in d.tblComidaPreferidas from c in d.tblLugarNacimientoes select new { _nombre = a.Nombre, _comida = b.ComidaPreferida, _lNacimiento = c.Ciudad }; foreach (var i in query) { Console.WriteLine($"{i._nombre } le gusta {i._comida} y nació en {i._lNacimiento}"); }