我們的初始查詢由許多基於使用單列(productId)的連接正常工作的子查詢組成。產生的模型映射到一個網格,該網格列出了昨天,今天和明天的產品名稱及其各自所需的數量。LINQ多列加入
但是,基於產品的使用年限收到了額外差異因素的要求,因此需要修改原始查詢。
因此,以下代碼是使用單個字段(ProductId作爲關鍵字)的工作代碼的修改。在試圖修改查詢使用多列密鑰(產品編號及年齡)我遇到了麻煩,接收以下錯誤:
The type of one of the expressions in the join clause is incorrect. Type inference failed in the call to 'GroupJoin'.
在創建不同的集合前面的查詢,我改變了關鍵的複合ProductId和年齡,並將新的匿名類型記憶體productKey設置爲新{pr.productId,pr.age}。然後在最終查詢中,我試圖在productKey上等待新結果等於new {y.productId,y.age}(y表示加入結果「昨天」)。
當我將鼠標懸停在每個連接結果(gr.productKey和y.productKey)的鍵的,下面是顯示每個:
'b 'a.productKey
Anonymous Types:
'a is new {'b productKey, int productId, string age,... }
'b is new {int productId, string age}
由於兩者都是類型的「B一個new {int productId,string age}我期待成功;然而,編譯器仍然不合作。我相信新的{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導致類似的結果,我也試了幾個變化基於這樣在該網站類似的問題,但不限於以下內容:
join y in yesterday on new {Key1 = gr.productId,Key2 = gr.age} equals y.productKey into outer0
join y in yesterday on new { gr.productId, gr.age } equals y.productKey into outer0
此外,原來的查詢,這修改工作順利進行。我很確定這是「有一點知識,是一件危險的事情」之一。或者也許只是「小知識」問題。無論哪種方式,我希望LINQ Gods能夠看到一個解決方案。對於多列鍵,而不是使用匿名
當我進行上述更改時,出現錯誤消息,指出「至少有一個對象必須實現IComparable。」這顯示在上述所有查詢中,「昨天」,「grp」和「模型」以及未顯示的那些查詢(「現在」和「明天」),但是與查詢「昨天」相同。 – 2011-12-30 08:02:35
@ user946045:IComparable定義了CompareTo方法,它告訴如何比較兩個類的實例。這是訂購所必需的,但在這種情況下,我認爲,最好是按特定列排序 - 更新 – PanJanek 2011-12-30 08:08:27
到目前爲止,創建productKey類看起來好像向後退出了2步。當我對最後一個查詢中的所有查詢使用匿名類型時,每一步都會得到準確的結果。當我使用一個定義的類時,我得到一個IComparable錯誤,我無法使用Order By子句。 – 2011-12-30 08:40:13