LINQ:结合加入和分组依据
Posted
技术标签:
【中文标题】LINQ:结合加入和分组依据【英文标题】:LINQ: combining join and group by 【发布时间】:2012-02-28 17:06:39 【问题描述】:我有一个结合了联接和组的查询,但我遇到了问题。查询是这样的:
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
。
知道我做错了什么吗?
【问题讨论】:
【参考方案1】:完成此操作后
group p by p.SomeId into pg
您不再有权访问初始 from
中使用的范围变量。即不能再谈p
或bp
,只能谈pg
。
现在,pg
是一个组,因此包含多个产品。给定pg
组中的所有产品都具有相同的SomeId
(因为这是您的分组依据),但我不知道这是否意味着它们都具有相同的BaseProductId
。
要获得基本产品名称,您必须在pg
组中选择一个特定产品(就像您对SomeId
和CountryCode
所做的那样),然后然后加入@ 987654334@。
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
;
也就是说,这看起来很不寻常,我认为您应该退后一步,考虑一下您实际上要检索的内容。
【讨论】:
这比我们的解决方案更好:) 谢谢。 @AakashM 谢谢。但我正在获取 groupVariable.FirstOrDefault().column_name 的问题。当我要访问 IQueryable 变量 Result 时发生错误,标题为 “entitycommandexecutionexception 未被用户代码处理” 正文 “执行命令定义时发生错误。有关详细信息,请参阅内部异常。” 我不明白发生了什么。 @MuhammadAshikuzzaman 听起来你需要Ask a new question。请务必包含所有详细信息!FirstOrDefault()
总是返回空值。我让它与pg.Key
一起工作,这实际上更有意义。我不明白FirstOrDefault
将如何返回任何对象,而我的分组依据是someId
@SZT 一旦你完成了group
,你最终得到的东西(pg
这里)就是IGrouping
。当您使用任何在IGrouping
上执行枚举类型的方法时,您正在迭代的是该组的成员。所以pg.FirstOrDefault()
是特定SomeId
组中Products
中的第一个(按任意顺序)。【参考方案2】:
我们是这样做的:
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
;
编辑:我们使用了 AakashM 的版本,因为它有更好的性能
【讨论】:
【参考方案3】:我遇到了和你一样的问题。
我将两个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
;
【讨论】:
以上是关于LINQ:结合加入和分组依据的主要内容,如果未能解决你的问题,请参考以下文章