Come eseguire l’unione tra più tabelle in LINQ lambda

Sto cercando di eseguire un join tra più tabelle in LINQ. Ho le seguenti classi:

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

E io uso il seguente codice (dove product , category e productcategory sono istanze delle classi precedenti):

 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}); 

Con questo codice ottengo un object dalla seguente class:

 QueryClass { productproductcategory, category} 

Dove productproductcategory è di tipo:

 ProductProductCategoryClass {product, productcategory} 

Non capisco dove sia la “tabella” unita, mi aspettavo una singola class che contenga tutte le proprietà delle classi coinvolte.

    Il mio objective è quello di popolare un altro object con alcune proprietà risultanti dalla query:

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

    come posso raggiungere questo objective?

    Per i join, preferisco fortemente la syntax della query per tutti i dettagli che sono felicemente nascosti (non ultimo dei quali sono gli identificatori trasparenti coinvolti con le proiezioni intermedie lungo il percorso che sono evidenti nell’equivalente della syntax del punto). Tuttavia, hai chiesto riguardo a Lambdas che penso tu abbia tutto ciò di cui hai bisogno – hai solo bisogno di mettere tutto insieme.

     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 }); 

    Se è necessario, è ansible salvare il join in una variabile locale e riutilizzarlo in un secondo momento, tuttavia in mancanza di altri dettagli contrari, non vedo alcun motivo per introdurre la variabile locale.

    Inoltre, puoi lanciare il Select nell’ultimo lambda del secondo Join (di nuovo, a condizione che non ci siano altre operazioni che dipendono dai risultati del join) che darebbe:

     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 }); 

    … e facendo un ultimo tentativo di venderti sulla syntax della query, questo sarebbe simile a questo:

     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 }; 

    Le tue mani potrebbero essere legate se la syntax delle query è disponibile. So che alcuni negozi hanno questi mandati, spesso basati sul concetto che la syntax delle query è un po ‘più limitata della syntax dei punti. Ci sono altri motivi, come “perché dovrei imparare una seconda syntax se posso fare tutto e di più in dot-syntax?” Come mostra quest’ultima parte – ci sono dettagli che nascondono la syntax della query che può farla valere la pena abbracciarla con il miglioramento della leggibilità che porta: tutte quelle proiezioni e identificatori intermedi che devi cucinare sono felicemente non front-and-center- fase nella versione query-syntax: sono background fluff. Fuori dalla mia scatola di soap ora – comunque, grazie per la domanda. 🙂

    Quello che hai visto è quello che ottieni – ed è esattamente quello che hai chiesto, qui:

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

    Questa è un’espressione lambda che restituisce un tipo anonimo con queste due proprietà.

    Nel tuo CategorizedProducts, devi solo passare attraverso quelle proprietà:

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

    dare un’occhiata a questo codice di esempio dal mio progetto

     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 questo codice mi sono unito a 3 tavoli e ho spited condizioni di join da dove clausola

    nota: le classi Servizi sono solo deformate (incapsulate) delle operazioni del database

      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}"); }