【发布时间】:2011-12-30 07:08:27
【问题描述】:
我们的初始查询由许多可以正常工作的子查询组成,这些子查询基于使用单个列 (productId) 的连接。生成的模型映射到一个网格,其中列出了产品名称以及昨天、今天和明天各自所需的数量。
但是,收到了基于产品使用年限的附加差异化因素的要求,因此有必要修改原始查询。
因此,以下代码是对工作代码的修改,它使用单个字段 ProductId 作为键。在尝试修改查询以使用多列键(ProductId 和 Age)时,我遇到了麻烦,收到以下错误:
连接子句中的其中一个表达式的类型不正确。调用“GroupJoin”时类型推断失败。
在前面创建 Distinct Aggregate 的查询中,我将键更改为 ProductId 和 age 的组合,并将匿名类型的新成员 productKey 分配给 new { pr.productId , pr.age }。然后在最后的查询中,我试图加入这个结果 on productKey equals new { y.productId, y.age } (y 代表加入结果“昨天”)。
当我将鼠标悬停在连接结果的每个键(gr.productKey 和 y.productKey)上时,每个键都会显示以下内容:
'b'a.productKey
匿名类型:
'a 是新的 {'b productKey, int productId, string age,... }
'b 是新的 {int productId, string age}
由于两者都是 'b 类型的 new {int productId, string age} 我期待成功;但是,编译器仍然不合作。我相信一个 new {int,string} 与另一个相同,无论名称如何。
var yesterday = from p in productOrdered
where p.deliveryDate.Date == DateTime.Now.AddDays(-1).Date
group p by new { p.id, p.age } into g
orderby g.Key
select new {
productKey = g.Key,
productId = g.Max(s => s.id),
age = g.Max(s => s.age),
quantity = g.Count(),
weight = g.Sum(s => s.weight),
};
var grp = (from pr in prods2
group pr by new { pr.productId, pr.age } into g
orderby g.Key
select new {
productKey = g.Key,
productId = g.Max(s => s.productId),
age = g.Max(s => s.age),
code = g.Max(s => s.code),
product = g.Max(s => s.product),
uom = g.Max(s => s.uom)
}).Distinct();
var model = from gr in grp
join y in yesterday on gr.productKey equals new { y.productId, y.age } into outer0
from y in outer0.DefaultIfEmpty()
join n in now on gr.productKey equals new { n.productId, n.age } into outer1
from n in outer1.DefaultIfEmpty()
join t in tomorrow on gr.productKey equals new { t.productId, t.age } into outer2
from t in outer2.DefaultIfEmpty()
select new RequiredProductsViewModel
{
ProductId = gr.productId,
Aged = gr.age,
Code = gr.code.ToString(),
Description = gr.product.ToString(),
MinusQ = (!(null == y) ? y.quantity : 0),
MinusW = (!(null == y) ? decimal.Parse(y.weight.ToString()) : 0),
ZeroQ = (!(null == n) ? n.quantity : 0),
ZeroW = (!(null == n) ? decimal.Parse(n.weight.ToString()) : 0),
OneQ = (!(null == t) ? t.quantity : 0),
OneW = (!(null == t) ? decimal.Parse(t.weight.ToString()) : 0),
UofM = gr.uom.ToString()
};
在 LINQPad 中进行测试得到了类似的结果,我还根据本网站上的类似问题尝试了几种变体,例如但不限于以下问题:
在昨天加入 y 新的 {Key1 = gr.productId,Key2 = gr.age} 等于 y.productKey 进入 outer0
在昨天加入 y new { gr.productId, gr.age } 等于 y.productKey 进入 outer0
同样,此修改所依据的原始查询成功运行。我很确定这是“一点知识,是一件危险的事情”问题之一。或者也许只是“小知识”问题。无论哪种方式,我都希望 LINQ 大神们能找到解决方案。
【问题讨论】:
标签: linq join left-join multiple-columns