Languague/C# / / 2025. 4. 9. 08:00

[C# LINQ] GroupJoin 사용법, null 처리(System.NullReferenceException: 'Object referenc

300x250

지난 편에서는 LINQ Join()을 정리했었다.
이번엔 그 연장선으로 GroupJoin()을 다뤄보려고 한다.
한 줄 요약하면 “1:N 관계 조인할 때 쓰는 Join”이다.



📚 목차

  1. GroupJoin이란?
  2. 실전 예제: 고객 + 주문
  3. SelectMany로 펼치기 (평탄화)
  4. 오류 예시 & 해결법
  5. 마무리

1. GroupJoin이란?

GroupJoin()한 항목(1개)에 여러 항목(N개)이 연결되는 구조일 때 사용한다.
예: 고객 1명이 여러 주문을 할 수 있을 때 = 고객 : 주문 = 1 : N

구조는 이렇게 생겼다:

var 결과 = 컬렉션1.GroupJoin(
    컬렉션2,
    x => x.기준값,
    y => y.기준값,
    (x, y목록) => 새로운형태
);
  • x: 기준이 되는 항목 (1)
  • y목록: 매칭되는 항목들의 목록 (N)

2. 실전 예제: 고객 + 주문

고객 1명에 여러 주문이 연결된 예제다.

var customers = new List<Customer>
{
    new Customer { Id = 1, Name = "홍길동" },
    new Customer { Id = 2, Name = "김영희" },
    new Customer { Id = 3, Name = "이철수" }
};

var orders = new List<Order>
{
    new Order { Id = 101, CustomerId = 1, Product = "노트북" },
    new Order { Id = 102, CustomerId = 1, Product = "마우스" },
    new Order { Id = 103, CustomerId = 2, Product = "키보드" }
};

var result = customers.GroupJoin(
    orders,
    c => c.Id,
    o => o.CustomerId,
    (c, orderList) => new { c.Name, Orders = orderList }
);

foreach (var item in result)
{
    Console.WriteLine($"{item.Name}님의 주문 목록:");
    foreach (var order in item.Orders)
    {
        Console.WriteLine($" - {order.Product}");
    }
}
홍길동님의 주문 목록:
 - 노트북
 - 마우스
김영희님의 주문 목록:
 - 키보드
이철수님의 주문 목록:

→ 주문이 없는 이철수도 결과엔 포함됨. 이게 GroupJoin의 장점이다.


3. SelectMany로 펼치기 (평탄화)

방금 결과는 IEnumerable<IEnumerable<>> 구조라 출력이 중첩된다.
한 줄로 펴고 싶을 때SelectMany()를 쓴다.

var flattened = customers.GroupJoin(
    orders,
    c => c.Id,
    o => o.CustomerId,
    (c, os) => new { c.Name, Orders = os.DefaultIfEmpty() }
)
.SelectMany(
    x => x.Orders,
    (c, o) => new { c.Name, Product = o?.Product ?? "주문 없음" }
);

foreach (var item in flattened)
{
    Console.WriteLine($"{item.Name} - {item.Product}");
}
홍길동 - 노트북
홍길동 - 마우스
김영희 - 키보드
이철수 - 주문 없음

 

DefaultIfEmpty()로 null 처리도 가능하다.


4. 오류 예시 & 해결법

❌ 문제 1: null 참조 오류

foreach (var order in item.Orders)
{
    Console.WriteLine(order.Product); // order가 null이면 에러
}

 

→ 주문이 없는 경우 order가 null이 될 수 있다.

System.NullReferenceException: 'Object reference not set to an instance of an object.'

 
✅ 해결법:

Console.WriteLine(order?.Product ?? "주문 없음");

❌ 문제 2: GroupJoin 했는데 결과가 없음
→ 키 값 타입이 다르면 매칭 안 된다.

Customer.Id = int,  Order.CustomerId = string → 실패

 
✅ 해결법: 타입 맞춰주기

orders.Select(o => new Order {
    Id = o.Id,
    CustomerId = int.Parse(o.CustomerId),
    Product = o.Product
});

5. 마무리

GroupJoin은 1:N 관계에서 진가를 발휘하는 LINQ 기능이다.

  • 중첩 결과가 기본이라 SelectMany()로 평탄화 필요
  • null 오류는 거의 항상 따라오니 ?., ?? 필수
  • 타입 mismatch는 눈치 못 챘다가 데이터가 안 나오는 원인 1위

다음 편에서는 Join vs GroupJoin을 비교하면서, 언제 어떤 걸 써야 할지 정리해보려 한다 😎

300x250
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유