Для модульного тестирования мы используем в коллекциях памяти, чтобы проверить логику наших запросов LINQ.Но в приведенном ниже сценарии я вижу различия между результатами LINQ to SQL и In Memory.
Для этого примера у нас есть три таблицы Customer, Order, Item.Я бы хотел подсчитать все товары, заказанные клиентом.Я хотел бы показать клиентам, которые также не заказали никаких товаров.В SQL это было бы внешним соединением.В LINQ to SQL я написал это ...
var itemCounts =
from c in Customer
from o in Order.Where(oo=>o.CustomerId==c.CustomerId).DefaultIfEmpty()
from i in Item.Where(ii=>i.OrderId==o.OrderId).DefaultIfEmpty()
group i by new { i.ItemId, c.CustomerId } into ig
select new ItemCountResult {
CustomerId = ig.Key.CustomerId,
Count = ig.Count()
};
Это прекрасно работает, когда мы идем против базы данных.Мы получаем клиентов с заказами и без, а также с учетом.Когда мы заменяем модульное тестирование в коллекциях памяти, мы видим, что ссылка на объект не является исключением.Я сузил его до строки «i.OrderId == o.OrderId», в частности, o имеет значение null.
Исходя из того, как работает DefaultIfEmpty, на самом деле это поведение, которое я ожидал бы.DefaultIfEmpty возвращает один перечисляемый элемент, равный нулю.
Итак, как мне исправить этот код для работы в обоих сценариях?
ОБНОВЛЕНИЕ: Пока я упрощал проблему, я потерялнекоторые важные части информации.Итак, позвольте мне повторить проблему.
У клиента 0-n заказов.Заказ имеет 1-н пунктов.У Товара есть 1-й Заказ.
Мне нужен список Товаров вместе с количеством клиентов, которые заказали этот товар.Если 0 клиентов заказали товар, я бы хотел, чтобы он все еще был возвращен, но с счетом 0.
Проблема заключается в том, что между Орденом и Предметом много-много, что мешает мне использовать синтаксис соединения.
У меня сейчас что-то вроде этого (надеюсь, на этот раз без опечаток):
var counts =
from i in Items
from oi in OrderItems.Where(z=>z.ItemId==i.ItemId).DefaultIfEmpty()
from o in Orders.Where(z=>z.OrderId==oi.OrderId).DefaultIfEmpty()
from c in Customers.Where(z=>z.CustomerId==o.CustomerId).DefaultIfEmpty()
group c by new { i.ItemId, c.CustomerId } into cg
select new CountResult {
CustomerId = cg.Key.CustomerId,
Count = cg.Count()
};