티스토리 뷰

.NET/C#

LINQ 의 OUTER JOIN 작업

POWERUMC 2007. 9. 4. 00:24
LINQ 를 이용한 OUTER JOIN 을 해보자.
이번 강좌를 지난 강좌에 이어 LINQ to SQL Classes 항목을 추가 하여야 한다.
이부분에 대해서는 다음의 URL 을 참고하기 바란다.
 
 
 
우선 우리가 원하는 SQL 쿼리식을 보자
 
SELECT A.ArticleNo, C.Content, C.InsertDate
FROM Article A
LEFT OUTER JOIN Comment C ON C.ArticleNo = A.ArticleNo
ORDER BY C.InsertDate DESC
 
아주 간단한 OUTER JOIN 의 예이다.
이 쿼리의 결과는 다음과 같다.
 
 
위 그림은 보시다시피 결과 데이터의 중하단 쯤에 나온 결과이다.
쿼리를 보듯 NULL 값이 주루룩 있다. 당연히 INNER JOIN 되지 않은 데이터는 NULL 값이 표시될 것이다.
 
 
그럼 LINQ 의 확장 메서드를 통한 OUTER JOIN 을 해보자.
 
var joinList = db.Articles.GroupJoin(
             db.Comments,
             _article => _article.ArticleNo,
             _comment => _comment.ArticleNo,
             (_article, c) => c.DefaultIfEmpty().Select(
                    _comment => new
                    {
                           ArticleNo = _article == null ? -1 : _article.ArticleNo,
                           CommentContent = _comment.Content ?? string.Empty,
                           InsertDate = _comment.InsertDate.ToString() ?? string.Empty
                    }
             )
             ).SelectMany(obj => obj)
             .OrderByDescending(o => o.InsertDate);
 
 
위 식을 INNER JOIN 식과 비교해 보았을 때, 좀 더 부가적인 작업이 필요하다.
 
c.DefaultIfEmpty()
 
을 통해 JOIN 가능한 키가 없을 경우에 따로 처리를 해주어야 한다.
 
또한, 키가 없을 경우의 데이터 또한 nullable 의 ?? operator 를 통해 null 데이터에 대한 경우에 대한 작업을 해야한다.
 
SelectMany(obj => obj)
 
확장 메서드를 통해 반복이 가능한 순환자(열거자) 에 대한 키(Key)값을 모두 반환한다.
 
아무리 람다식을 이용해 코딩양을 줄였다고 하더라고, 사실 벅찬 감이 무척 많다..
두개의 테이블이지만, 3-4 개의 테이블이라고 생각하면, 아마도 SQL 쿼리를 이용하는 것이 나을 것이다.
 
 
그렇지만 다음의 LINQ 식을 이용한 쿼리를 보도록 하자.
 
var joinList = from a in db.Articles
             join c in db.Comments on a.ArticleNo equals c.ArticleNo into _c
             from c in _c.DefaultIfEmpty()
             orderby c.InsertDate descending
             select new
             {
                       ArticleNo = a.ArticleNo,
                       CommentContent = c.Content,
                       InsertDate = c.InsertDate.ToString()
             };
 
개체를 이용한 쿼리식에 비해 무척이나 SQL 쿼리와 가까워 졌다.
 
join c in db.Comments on a.ArticleNo equals c.ArticleNo into _c
from c in _c.DefaultIfEmpty()
 
를 보면, into 키워드를 통해 join 데이터를 _c 컬렉션에 담고
다시 _c.DefaultIfEmpty() 를 통해 null 데이터를 처리하고 있다.
 
into 키워드는 LINQ 의 출연과 함께, 쿼리식 뿐만 아니라 통계 쿼리에도 자주 등장하게 될 키워드이다.
 
그럼, 다음 아티클을 스스로 기대하며 이만^^
댓글