Наш начальный запрос состоит из множества подзапросов, которые работают правильно, на основе объединений, которые используют один столбец (productId). Полученная модель сопоставляется с сеткой, в которой перечислены названия продуктов вместе с их соответствующими необходимыми количествами на вчера, сегодня и завтра.
Однако было получено требование для дополнительного дифференциатора в зависимости от возраста продукта, и поэтому было необходимо изменить исходный запрос.
Итак, следующий код является модификацией рабочего кода, который использует одно поле, ProductId в качестве ключа. При попытке изменить запрос для использования ключа из нескольких столбцов (ProductId и Age) я столкнулся с проблемой, получив следующую ошибку:
Неверно указан тип одного из выражений в предложении соединения. Ошибка вывода типа при вызове 'GroupJoin'.
В предыдущем запросе, который создает Distinct Aggregate, я изменил ключ на составную часть ProductId и age и назначил новый член анонимного типа, productKey для new {pr.productId, pr.age} . Затем в последнем запросе я пытаюсь объединить этот результат для productKey равно new {y.productId, y.age} (y, представляющий результат объединения "вчера").
При наведении курсора на каждую из клавиш объединенных результатов (gr.productKey и y.productKey) для каждого из них отображается следующее:
'b' a.productKey
Анонимные типы:
'a is new {' b productKey, int productId, string age, ...}
'b is new {int productId, age string}
Так как оба типа 'b a new {int productId, age string} Я ожидал успеха; тем не менее, компилятор по-прежнему не работает. Я верю, что один 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 вчера во new {Key1 = gr.productId, Key2 = gr.age} равно y.productKey в external0
присоединяйтесь к y вчера во new {gr.productId, gr.age} равно y.productKey в external0
Опять же, исходный запрос, на котором выполняется эта модификация, успешно работает. Я почти уверен, что это одна из проблем "немного знаний, это опасная вещь". Или, может быть, просто «мало знаний». В любом случае, я надеюсь, что Боги LINQ смогут найти решение.