단위 테스트의 경우 메모리 컬렉션에서 LINQ 쿼리의 논리를 확인합니다. 그러나 아래 시나리오에서는 LINQ와 SQL의 결과와 메모리의 결과 간 차이점을 확인했습니다.DefaultIfEmpty - LINQ to SQL 대 메모리 있음
이 예에서는 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는 null의 열거 가능한 단일 요소를 리턴합니다.
그럼이 코드를 두 시나리오에서 모두 작동하도록 수정하려면 어떻게해야합니까?
업데이트 : 나는이 문제를 단순화하는 동안 몇 가지 중요한 정보를 잃어 버렸습니다. 문제를 다시 설명하겠습니다.
고객에게 0-n 주문이 있습니다. 주문에 1-n 품목이 있습니다. 항목에 1-n 주문이 있습니다.
해당 항목을 주문한 고객 수와 함께 항목 목록이 필요합니다. 0 고객이 항목을 주문한 경우에도 0이 계속 반환되지만 반환되기를 원합니다.
문제는 Join-into 구문을 사용하지 못하게하는 Order와 Item 사이의 다 대다 문제입니다.
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()
};
가 나는 O를 잘못 입력 문제를 단순화 동안 : 조인 명시 적으로 사용하여 다시, 여기
다른 대안을 것 :
올바른 관계가 설정 한 가정, 대신 시도 대. 나는 또한 우리가 가진 관계를 버렸다. Item to Order는 실제로는 many-to-many가 아닌 one-to-many 아이템입니다. 죄송합니다. 대체 조인 구문을 사용하면 문제가 해결되지만 올바른 것입니다.하지만 다 대 다 상황에서 제대로 작동하지 않습니다. 위의 내 문제를 업데이 트합니다. – joegtp