J'ai une requête qui combine une jointure et un groupe, mais j'ai un problème. La requête est comme:
var result = from p in Products
join bp in BaseProducts on p.BaseProductId equals bp.Id
group p by p.SomeId into pg
select new ProductPriceMinMax {
SomeId = pg.FirstOrDefault().SomeId,
CountryCode = pg.FirstOrDefault().CountryCode,
MinPrice = pg.Min(m => m.Price),
MaxPrice = pg.Max(m => m.Price),
BaseProductName = bp.Name <------ can't use bp.
};
Comme vous le voyez, il joint la table Products à la table BaseProducts et se groupe sur un identifiant de la table Product. Mais dans le produit ProductPriceMinMax résultant, j'ai également besoin d'une propriété de la table BaseProducts: bp.Name, mais elle ne connaît pas bp.
Une idée de ce que je fais mal?
Merci!
Une fois que vous avez fait cela
group p by p.SomeId into pg
vous n'avez plus accès aux variables de plage utilisées dans le from
initial. C'est-à-dire que vous ne pouvez plus parler de p
ou de bp
, vous ne pouvez parler que de pg
.
Maintenant, pg
est un groupe et contient donc plus d'un produit. Tous les produits d'un groupe pg
donné ont le même SomeId
(puisque c'est ce que vous avez groupé par), mais je ne sais pas si cela signifie qu'ils ont tous le même BaseProductId
.
Pour obtenir un nom de produit de base, vous devez choisir un produit particulier dans le groupe pg
(comme vous le faites avec SomeId
et CountryCode
), et puis rejoignez BaseProducts
.
var result = from p in Products
group p by p.SomeId into pg
// join *after* group
join bp in BaseProducts on pg.FirstOrDefault().BaseProductId equals bp.Id
select new ProductPriceMinMax {
SomeId = pg.FirstOrDefault().SomeId,
CountryCode = pg.FirstOrDefault().CountryCode,
MinPrice = pg.Min(m => m.Price),
MaxPrice = pg.Max(m => m.Price),
BaseProductName = bp.Name // now there is a 'bp' in scope
};
Cela dit, cela semble assez inhabituel et je pense que vous devriez prendre du recul et considérer ce que vous essayez réellement de récupérer.
Nous l'avons fait comme ça:
from p in Products
join bp in BaseProducts on p.BaseProductId equals bp.Id
where !string.IsNullOrEmpty(p.SomeId) && p.LastPublished >= lastDate
group new { p, bp } by new { p.SomeId } into pg
let firstproductgroup = pg.FirstOrDefault()
let product = firstproductgroup.p
let baseproduct = firstproductgroup.bp
let minprice = pg.Min(m => m.p.Price)
let maxprice = pg.Max(m => m.p.Price)
select new ProductPriceMinMax
{
SomeId = product.SomeId,
BaseProductName = baseproduct.Name,
CountryCode = product.CountryCode,
MinPrice = minprice,
MaxPrice = maxprice
};
EDIT: nous avons utilisé la version d’AakashM, car elle offre de meilleures performances.
J'ai rencontré le même problème que toi.
J'enfonce deux tables
result
dans t1
objet et groupe t1
.
from p in Products
join bp in BaseProducts on p.BaseProductId equals bp.Id
select new {
p,
bp
} into t1
group t1 by t1.p.SomeId into g
select new ProductPriceMinMax {
SomeId = g.FirstOrDefault().p.SomeId,
CountryCode = g.FirstOrDefault().p.CountryCode,
MinPrice = g.Min(m => m.bp.Price),
MaxPrice = g.Max(m => m.bp.Price),
BaseProductName = g.FirstOrDefault().bp.Name
};