LINQ:结合连接和分组
我有一个查询,结合了一个连接和一个组,但我有一个问题。 查询如下所示:
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. };
如您所见,它将Products表与BaseProducts表连接起来,并将其分组在Product表的id上。 但在生成的ProductPriceMinMax中,我还需要BaseProducts表的一个属性:bp.Name,但它不知道bp。
任何想法我做错了什么?
谢谢!
一旦你完成了这个
group p by p.SomeId into pg
您不再有权访问最初使用的范围variables。 也就是说,你不能再谈论p
或bp
,你只能谈论pg
。
现在, pg
是一个组 ,因此包含多个产品。 在给定的pg
组中的所有产品都具有相同的SomeId
(因为这就是你分组的),但我不知道这是否意味着它们都具有相同的BaseProductId
。
要获得基本的产品名称,您必须在pg
组中select一个特定的产品(如您使用SomeId
和SomeId
), 然后join到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 };
也就是说,这看起来很不寻常,我认为你应该退一步,考虑你实际上想要找回的东西。
我们这样做:
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 => mpPrice) let maxprice = pg.Max(m => mpPrice) select new ProductPriceMinMax { SomeId = product.SomeId, BaseProductName = baseproduct.Name, CountryCode = product.CountryCode, MinPrice = minprice, MaxPrice = maxprice };
编辑:我们使用AakashM的版本,因为它有更好的性能
我遇到了和你一样的问题。
我将两个tables
result
推入t1
对象和组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 };