내부 조인이란?
내부 조인은 두 개 이상의 데이터 집합에서 일치하는 데이터만 반환합니다. 만약, 일치하는 데이터가 없는 경우 반환되는 데이터는 존재하지 않습니다.
즉, 내부 조인은 두 개 이상의 데이터 집합에서 일치하는 결과를 추출하고 싶은 경우 사용됩니다.
다음 예시를 통해 알아봅시다. 두 개의 데이터 집합(Employee, Department)이 존재합니다.
Employee 데이터 집합의 부서 코드가 Department 데이터 집합의 부서 코드에 존재하는 데이터를 추출하려고 합니다.
부서 코드 2000은 Department 데이터 집합의 부서 코드에 존재하지 않으므로 나랑두 사원은 결과에 포함되지 않습니다.
Join 메서드
C#의 Linq에서 제공하는 Join() 메서드를 사용하여 두 개의 데이터 집합을 조인할 수 있습니다. Join() 메서드는 두 가지 오버로드된 버전이 존재하며, 비교자를 사용한다는 차이점이 있습니다.
public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>(
this IEnumerable<TOuter> outer,
IEnumerable<TInner> inner,
Func<TOuter, TKey> outerKeySelector,
Func<TInner, TKey> innerKeySelector,
Func<TOuter, TInner, TResult> resultSelector);
public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>(
this IEnumerable<TOuter> outer,
IEnumerable<TInner> inner,
Func<TOuter, TKey> outerKeySelector,
Func<TInner, TKey> innerKeySelector,
Func<TOuter, TInner, TResult> resultSelector,
IEqualityComparer<TKey> comparer);
Join() 메서드를 사용하기 위해 다음 내용을 숙지합시다.
외부 데이터 소스
- Join() 메서드를 호출하는 데이터 집합입니다.
내부 데이터 소스
- Join() 메서드를 호출하는 데이터 집합과 Join되는 데이터 집합입니다.
- 내부 데이터 소스는 Join() 메서드의 첫 번째 매개변수입니다.
- IEnumerable<TInner> inner
외부 키 선택자
- 외부 데이터 소스(Join() 메서드를 호출하는 데이터 집합)에서 Join에 필요한 키를 가져옵니다.
- 외부 키 선택자는 Join() 메서드의 두 번째 매개변수입니다.
- Func<TOuter, TKey> outerKeySelector
내부 키 선택자
- 내부 데이터 소스(Join() 메서드의 첫 번째 매개변수)에서 Join에 필요한 키를 가져옵니다.
- 내부 키 선택자는 Join() 메서드의 세 번째 매개변수입니다.
- Func<TInner, TKey> innerKeySelector
결과 선택자
- Join 결과에서 추출하고 싶은 데이터를 작성합니다.
- Select절과 유사합니다.
- 결과 선택자는 Join() 메서드의 네 번째 매개변수입니다.
- Func<TOuter, IEnumerable<TInner>, TResult> resultSelector
샘플 데이터
이번 포스팅에서는 사용자 정의 클래스인 Employee, Department, Address 타입의 데이터 집합을 사용합니다.
[Employee 클래스]
public class Employee {
public string Emp_Code { get; set; } // 사원코드
public string Emp_Name { get; set; } // 사원명
public string Dept_Code { get; set; } // 부서코드
public static List<Employee> GetEmployees()
{
return new List<Employee>()
{
new Employee { Emp_Code = "1", Emp_Name = "홍길동", Dept_Code = "1000"},
new Employee { Emp_Code = "2", Emp_Name = "김첨지", Dept_Code = "2000"},
new Employee { Emp_Code = "3", Emp_Name = "나랑두", Dept_Code = "3000"}
};
}
}
[Department 클래스]
public class Department
{
public string Dept_Code { get; set; } // 부서코드
public string Dept_Name { get; set; } // 부서명
public static List<Department> GetDeptments()
{
return new List<Department>()
{
new Department { Dept_Code = "1000", Dept_Name = "영업"},
new Department { Dept_Code = "3000", Dept_Name = "기획"}
};
}
}
[Address 클래스]
public class Address
{
public string Emp_Code { get; set; } // 사원코드
public string Address_Name { get; set; } // 주소
public static List<Address> GetAddresses()
{
return new List<Address>()
{
new Address { Emp_Code = "1", Address_Name = "서울 어딘가"},
new Address { Emp_Code = "2", Address_Name = "부산 어딘가"}
};
}
}
예제 1. 질의 구문
다음 예제는 질의 구문을 사용하여 Employee 데이터 집합의 Emp_Code(사원코드)가 Address 데이터 집합의 Emp_Code(사원코드)에 존재하는 데이터를 추출합니다.
class Program
{
static void Main(string[] args)
{
var InnerJoinQueryResult = (from employee in Employee.GetEmployees() // 데이터 집합(Employee)
join address in Address.GetAddresses() // 데이터 집합(Address)
on employee.Emp_Code equals address.Emp_Code // 일치하는 프로퍼티
select new // 반환 결과 생성
{
Emp_Code = employee.Emp_Code,
Emp_Name = employee.Emp_Name,
Address_Name = address.Address_Name
});
foreach (var result in InnerJoinQueryResult)
{
Console.WriteLine("사원코드: " + result.Emp_Code + " / 사원명: " + result.Emp_Name + " / 주소: " + result.Address_Name);
}
}
}
[실행 결과]
사원코드: 1 / 사원명: 홍길동 / 주소: 서울 어딘가
사원코드: 2 / 사원명: 김첨지 / 주소: 부산 어딘가
예제 2. 메서드 구문
다음 예제는 메서드 구문을 사용하여 Employee 데이터 집합의 Emp_Code(사원코드)가 Address 데이터 집합의 Emp_Code(사원코드)에 존재하는 데이터를 추출합니다.
class Program
{
static void Main(string[] args)
{
var InnerJoinMethodResult = Employee.GetEmployees() // Join() 메서드를 호출하는 데이터 집합(Employee)
.Join(Address.GetAddresses(), // 연결하고자하는 데이터 집합(Address)
employee => employee.Emp_Code, // Join() 메서드를 호출하는 데이터 집합의 키(Employee 클래스의 Emp_Code)
address => address.Emp_Code, // 연결하고자하는 데이터 집합의 키(Address 클래스의 Emp_Code)
(employee, address) => new // 반환 결과 생성
{
Emp_Code = employee.Emp_Code,
Emp_Name = employee.Emp_Name,
Address_Name = address.Address_Name
});
foreach (var result in InnerJoinMethodResult)
{
Console.WriteLine("사원코드: " + result.Emp_Code + " / 사원명: " + result.Emp_Name + " / 주소: " + result.Address_Name);
}
}
}
[실행 결과]
사원코드: 1 / 사원명: 홍길동 / 주소: 서울 어딘가
사원코드: 2 / 사원명: 김첨지 / 주소: 부산 어딘가
예제 3. 3개 이상의 데이터 집합 조인
다음 예제는 3개 이상의 데이터 집합(Employee, Department, Address)을 조인하여 부서명, 사원명, 주소를 추출합니다.
순서 1. Employee 데이터 집합의 Dept_Code가 Department 데이터 집합의 Dept_Code와 일치하는 데이터 추출
순서 2. 1번 과정에서 추출된 데이터의 Emp_Code가 Address 데이터 집합의 Emp_Code와 일치하는 데이터 추출
class Program
{
static void Main(string[] args)
{
// 1. 질의 구문(Query Syntax)
var InnerJoinQueryResult = (from employee in Employee.GetEmployees()
join department in Department.GetDeptments()
on employee.Dept_Code equals department.Dept_Code
join address in Address.GetAddresses()
on employee.Emp_Code equals address.Emp_Code
select new
{
Dept_Name = department.Dept_Name,
Emp_Name = employee.Emp_Name,
Address_Name = address.Address_Name
});
// 2. 메서드 구문(Method Syntax)
var InnerJoinMethodResult = Employee.GetEmployees()
.Join(Department.GetDeptments(),
employee => employee.Dept_Code,
department => department.Dept_Code,
(employee, department) => new
{
Dept_Name = department.Dept_Name,
Emp_Code = employee.Emp_Code,
Emp_Name = employee.Emp_Name
})
.Join(Address.GetAddresses(),
joinResult => joinResult.Emp_Code,
address => address.Emp_Code,
(joinResult, address) => new
{
Dept_Name = joinResult.Dept_Name,
Emp_Name = joinResult.Emp_Name,
Address_Name = address.Address_Name
});
Console.WriteLine("질의 구문");
foreach (var result in InnerJoinQueryResult)
{
Console.WriteLine("부서명: " + result.Dept_Name + " / 사원명: " + result.Emp_Name + " / 주소: " + result.Address_Name);
}
Console.WriteLine("\n메서드 구문");
foreach (var result in InnerJoinMethodResult)
{
Console.WriteLine("부서명: " + result.Dept_Name + " / 사원명: " + result.Emp_Name + " / 주소: " + result.Address_Name);
}
}
}
[실행 결과]
질의 구문
부서명: 영업 / 사원명: 홍길동 / 주소: 서울 어딘가
메서드 구문
부서명: 영업 / 사원명: 홍길동 / 주소: 서울 어딘가
'C# > LINQ' 카테고리의 다른 글
[C#]LINQ 왼쪽 조인(Left Join) (0) | 2022.08.06 |
---|---|
[C#]LINQ 그룹 조인 - GroupJoin 메서드 (0) | 2022.08.06 |
[C#]LINQ 데이터 그룹화 - GroupBy 메서드 (1) | 2022.08.04 |
[C#]LINQ 누적기 함수 - Aggregate 메서드 (0) | 2022.08.03 |
[C#]LINQ 데이터 개수 구하기 - Count 메서드 (0) | 2022.07.31 |
댓글