J'essaye d'effectuer un jointure entre plusieurs tables dans LINQ. J'ai les cours suivants:
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 classe unique qui contient toutes les propriétés des classes impliquées.
Mon objectif est de renseigner 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?
Pour les jointures, je préfère fortement la syntaxe de requête pour tous les détails qui sont heureusement cachés (les identificateurs transparents impliqués dans les projections intermédiaires le long du chemin n'étant pas les moindres, comme en apparence dans l'équivalent de la syntaxe à points). 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 en ordre.
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 = m.c.CatId
// other assignments
});
Si vous en avez besoin, vous pouvez enregistrer la jointure dans une variable locale et la réutiliser ultérieurement, mais sans autre précision, je ne vois aucune raison d'introduire la variable locale.
De plus, vous pouvez jeter la Select
dans le dernier lambda du second Join
(encore une fois, à condition qu'aucune autre opération ne dépende du résultat de la jointure), ce qui donnerait:
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
});
... et faisant une dernière tentative pour vous vendre sur la syntaxe de requête, ceci ressemblerait à ceci:
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
};
Vos mains peuvent être liées si la syntaxe de requête est disponible. Je sais que certains magasins ont de tels mandats - souvent basés sur l’idée 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 seconde syntaxe si je peux tout faire et plus en syntaxe à points?" Comme le montre cette dernière partie, la syntaxe de la requête cache certains détails qui peuvent le rendre digne d'intérêt pour l'amélioration de la lisibilité: toutes les projections et les identifiants intermédiaires que vous devez préparer sont heureusement pas parfaitement centrés. étape dans la version de requête-syntaxe - ils sont fluff d'arrière-plan. Hors de ma boîte à savon maintenant - de toute façon, merci pour la question. :)
Ce que vous avez vu est ce que vous obtenez - et c'est exactement ce que vous avez demandé, ici:
(ppc, c) => new { productproductcategory = ppc, category = c}
C'est une expression lambda renvoyant un type anonyme avec ces deux propriétés.
Dans vos produits catégorisés, il vous suffit de passer par ces propriétés:
CategorizedProducts catProducts = query.Select(
m => new {
ProdId = m.productproductcategory.product.Id,
CatId = m.category.CatId,
// other assignments
});
regardez cet exemple de code de mon projet
public static IList<Letter> GetDepartmentLettersLinq(int departmentId)
{
IEnumerable<Letter> 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();
}
dans ce code, j'ai rejoint 3 tables et j'ai craché la condition de jointure de la clause où
remarque: les classes de services viennent juste de déformer (encapsuler) les opérations de base de données
public ActionResult Index()
{
List<CustomerOrder_Result> obj = new List<CustomerOrder_Result>();
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);
}
cela fait longtemps, mais ma réponse pourrait aider quelqu'un:
si vous avez déjà défini la relation correctement, vous pouvez utiliser ceci:
var res = query.Products.Select(m => new
{
productID = product.Id,
categoryID = m.ProductCategory.Select(s => s.Category.ID).ToList(),
}).ToList();
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}");
}