Dapper는 간단하고 가벼우며 널리 사용되는 .NET용 ORM(객체 관계 매퍼)입니다. 이전 기사에서 Dapper 작업의 기본 사항을 배웠습니다. 그리고 이전 기사에서 Dapper Extensions 라이브러리 작업에 대해 논의했습니다. 최근에는 Dapper의 몇 가지 고급 기능을 살펴보았습니다.
이 문서에서는 Dapper에서 관계 매핑 작업을 수행하는 방법을 알아봅니다. 구체적으로 Dapper를 사용하여 일대일, 일대다, 다대다 관계를 매핑하는 방법을 살펴보겠습니다.
이 문서에 제공된 코드 예제를 사용하려면 시스템에 Visual Studio 2022가 설치되어 있어야 합니다. 아직 복사본이 없다면 여기에서 Visual Studio 2022를 다운로드할 수 있습니다.
Visual Studio에서 ASP.NET Core 웹 API 프로젝트 만들기
먼저 Visual Studio 2022에서 ASP.NET Core 7 프로젝트를 만들어 보겠습니다. 다음 단계를 따르세요.
- Visual Studio 2022 IDE를 실행합니다.
- “새 프로젝트 만들기”를 클릭하세요.
- “새 프로젝트 만들기” 창에 표시된 템플릿 목록에서 “ASP.NET Core Web API”를 선택합니다.
- 다음을 클릭하세요.
- “새 프로젝트 구성” 창에서 새 프로젝트의 이름과 위치를 지정합니다.
- 선택적으로 기본 설정에 따라 “동일한 디렉터리에 솔루션과 프로젝트 배치” 확인란을 선택합니다.
- 다음을 클릭하세요.
- 다음에 표시되는 “추가 정보” 창에서 “컨트롤러 사용(최소 API를 사용하려면 선택 취소)” 확인란을 선택된 상태로 둡니다. 이 프로젝트에서는 최소한의 API를 사용하지 않습니다. “인증 유형”을 “없음”(기본값)으로 설정해 둡니다.
- “Open API 지원 활성화”, “HTTPS 구성” 및 “Docker 활성화” 확인란이 선택 해제되어 있는지 확인하세요. 여기서는 이러한 기능을 사용하지 않을 것입니다.
- 생성을 클릭합니다.
이 ASP.NET Core 7 Web API 프로젝트를 사용하여 아래 섹션에서 Dapper의 고급 기능을 사용하겠습니다.
대퍼란 무엇인가요? 왜 그것을 사용합니까?
객체 관계형 매퍼는 프로그래밍 언어의 객체 모델과 관계형 데이터베이스의 데이터 모델 간의 “임피던스 불일치”를 해결하는 데 사용됩니다. Dapper는 .NET 및 .NET Core를 위한 경량의 고성능 마이크로 ORM 프레임워크입니다. Oracle, SQL Server, Oracle, MySQL, PostgreSQL, SQLite 및 SQL CE와 같은 광범위한 데이터베이스를 지원합니다. Stack Overflow 팀은 .NET용 간단한 ORM으로 Dapper를 만들었습니다. Dapper는 GitHub에서 사용할 수 있는 오픈 소스 프로젝트입니다.
Dapper의 다중 매핑
Dapper는 다중 매핑을 지원하므로 한 데이터베이스 테이블의 단일 레코드를 다른 테이블의 여러 레코드에 매핑할 수 있습니다. 다중 매핑을 사용하면 하나의 쿼리로 여러 데이터베이스 테이블에서 데이터를 검색할 수 있습니다.
이를 수행하려면 Dapper의 쿼리 메서드를 호출할 때 SplitOn 매개 변수를 사용합니다. SplitOn 메서드는 데이터를 여러 개체로 분할하는 데 사용할 열을 지정합니다. 다음 두 클래스를 고려하십시오.
public class Author { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } } public class Book { public int Id { get; set; } public int AuthorId { get; set; } public string Title { get; set; } public string ISBN { get; set; } }
다음 코드 조각은 Dapper를 사용하여 다중 매핑을 구현하는 방법을 보여줍니다.
using (var connection = new SqlConnection(connectionString)){ string query = "SELECT * from Authors A Inner Join Books B ON A.Id = B.AuthorId"; var authors = connection.Query<Author, Book, Author>( query, (author, book) => { author.Books = author.Books ?? new List<Book>(); author.Books.Add(book); }, splitOn: "Id" ).Distinct().ToList(); }
Dapper의 간단한 매핑
아래 테이블에 나열된 필드가 있는 Store라는 데이터베이스 테이블을 생각해 보세요.
테이블 이름: 상점 |
|
분야 명 |
필드 유형 |
Store_Id(기본_키) |
정수(자동 생성) |
가게 이름 |
바르차르 |
위치 |
바르차르 |
—
다음 매개 변수화된 SQL 쿼리는 일치하는 Store_Id가 있는 Store 데이터베이스 테이블의 레코드를 반환합니다.
Select Store_Id, Store_Name, Location From Store Where Store_Id = @StoreId
Dapper를 사용하여 Store 데이터베이스 테이블에서 레코드를 검색하려면 다음 코드 조각을 사용합니다.
using var connection = new SqlConnection(); var stores = await connection.QueryAsync<Store>( sql, new { Store_Id = storeId });
Dapper의 일대일 관계 다중 매핑
아래 테이블에 나열된 필드가 있는 Order 및 Customer라는 두 개의 데이터베이스 테이블을 생각해 보세요.
테이블 이름: 순서 |
|
분야 명 |
필드 유형 |
Order_Id(기본_키) |
정수(자동 생성) |
Customer_Id(외부_키) |
정수 |
주문_날짜 |
날짜 시간 |
주문_수량 |
정수 |
주문_가격 |
더블 |
—
테이블 이름: 고객 |
|
분야 명 |
필드 유형 |
Customer_Id(기본_키) |
정수(자동 생성) |
이름 |
바르차르 |
성 |
바르차르 |
주소 |
바르차르 |
핸드폰 |
바르차르 |
이메일 |
바르차르 |
—
다음 SQL 쿼리를 사용하여 주문 기록 및 관련 고객 세부 정보를 선택할 수 있습니다.
Select o.Order_Id, o.Order_Date, c.Customer_Id, c.First_Name, c.Last_Name From Order o Inner Join Customer c On o.Customer_Id = c.Customer_Id
다음 코드는 Order와 Customer 데이터베이스 테이블 사이에 일대일 매핑을 설정하고 Dapper를 사용하여 주문 레코드를 검색하는 방법을 보여줍니다.
string query = "Select * From Order o Inner Join Customer c On o.Customer_Id = c.Customer_Id"; var orders = connection.Query<Order, Customer, Order>(query, map: (order, customer) => { order.Customer = customer; return order; }, splitOn: "Customer_Id").FirstOrDefault();
Dapper의 일대다 관계 다중 매핑
이제 추가 필드를 통합하기 위해 Order 테이블을 수정하겠습니다. 다음 데이터베이스 테이블은 두 엔터티인 Order와 Product 간의 일대다 관계를 보여줍니다. 즉, 여러 제품과 연결된 주문이 있을 수 있음을 의미합니다.
테이블 이름: 순서 |
|
분야 명 |
필드 유형 |
Order_Id(기본_키) |
정수(자동 생성) |
Product_Id(외부_키) |
정수 |
Customer_Id(외부_키) |
정수 |
주문_날짜 |
날짜 시간 |
주문_수량 |
정수 |
주문_가격 |
더블 |
—
테이블 이름: 제품 |
|
분야 명 |
필드 유형 |
Product_Id(기본_키) |
정수(자동 생성) |
상품명 |
바르차르 |
제품_수량 |
정수 |
단가 |
더블 |
—
이제 다음 SQL 쿼리를 사용하여 모든 주문을 검색할 수 있습니다.
Select Order_Id, Order_Quantity, Order_Date, p.Product_Name From Order o Inner Join Product p On o.Product_Id = p.Product_Id
다음 코드 조각은 Order 테이블과 Product 테이블 사이에 일대다 매핑을 설정하고 Dapper를 사용하여 주문 레코드를 검색하는 방법을 보여줍니다.
string query = "Select * From Order o Inner Join Product p On o.Product_Id = p.Product_Id"; var orders = connection.Query<Order, Product, Order>(query, map: (order, product) => { order.Product = product; return order; }, splitOn: "Product_Id;
Dapper의 다대다 관계 다중 매핑
다대다 관계는 좀 더 복잡합니다. 예를 들어, 한 학생이 여러 코스에 등록할 수 있는 동시에 하나의 코스를 여러 학생에게 매핑할 수도 있는 Student 및 Course 엔터티 간의 관계를 가질 수 있습니다. 즉, 다대다 관계를 통해 한 테이블의 여러 레코드를 다른 테이블의 여러 레코드와 연결할 수 있습니다.
이러한 관계는 일반적으로 “접합 테이블” 또는 “브리지 테이블”이라고도 하는 세 번째 테이블을 사용하여 구현됩니다. Dapper를 사용하여 다대다 관계를 매핑하려면 조인 테이블을 처리하고 여러 SQL 쿼리 또는 잘 구성된 하나의 쿼리를 만들어 관련 데이터를 가져와야 합니다.
아래 테이블에 표시된 것처럼 Student, Course 및 StudentCourse라는 세 개의 데이터베이스 테이블과 해당 필드를 고려하세요.
테이블 이름: 학생 |
|
분야 명 |
필드 유형 |
Student_Id (기본_키) |
정수(자동 생성) |
이름 |
바르차르 |
성 |
바르차르 |
주소 |
바르차르 |
—
테이블 이름: 코스 |
|
분야 명 |
필드 유형 |
Course_Id(기본_키) |
정수(자동 생성) |
강좌_제목 |
바르차르 |
강좌_기간 |
정수 |
시작_날짜 |
날짜 시간 |
—
테이블 이름: Student_Course |
|
분야 명 |
필드 유형 |
Student_Course_Id(기본_키) |
정수(자동 생성) |
Student_Id (Foreign_Key) |
정수 |
Course_Id(외국_키) |
정수 |
—
다음 클래스를 사용하여 학생과 코스 간의 관계를 표현할 수 있습니다.
public class Student { public int Student_Id { get; private set; } public string FirstName { get; set; } = string.Empty; public string LastName { get; set; } public string Address { get; set; } = string.Empty; public List<Course> Courses { get; set; } } public class Course { public int Course_Id { get; private set; } public string Course_Title { get; set; } public int Course_Duration { get; set; } public DateTime Start_Date { get; set; } public List<Student> Courses { get; set; } }
학생 및 강좌 수업의 목록을 참고하세요. Student 클래스에는 Courses 목록이 포함되어 있지만 Course 클래스에는 Students 목록이 포함되어 있습니다. 다음 SQL 문을 사용하여 학생 및 관련 데이터를 검색할 수 있습니다.
Select s.Student_Id, s.First_Name, s.Last_Name, c.Course_Title From Student s Inner Join Student_Course sc ON sc.Student_Id = s.Student_Id Inner Join Course c ON c.Course_Id = sc.Course_Id
Dapper에서 학생과 코스 엔터티 사이에 다대다 매핑을 설정하여 학생이 등록한 코스와 함께 학생 기록을 검색할 수 있습니다. 코드는 다음과 같습니다.
using(var connection = new SqlConnection(connectionString)) { string query = "Select s.Student_Id, s.First_Name, s.Last_Name, c.Course_Title From Student s " + "Inner Join Student_Course sc ON sc.Student_Id = s.Student_Id " + "Inner Join Course c ON c.Course_Id = sc.Course_Id"; var students = await connection.QueryAsync <Student, Course, Student > (query, (student, course) => { student.Courses.Add(course); return student; }, splitOn: "Course_Id"); }
Dapper는 .NET Core 애플리케이션의 데이터 액세스 기능을 크게 향상시킬 수 있는 뛰어난 기능을 갖춘 가볍고 성능이 뛰어나며 사용자 지정이 가능한 ORM입니다. 지금까지 살펴본 것처럼 Dapper는 관계 매핑에 대한 탁월한 지원을 제공합니다. 여기 향후 기사에서 Dapper 사용에 대해 더 자세히 설명하겠습니다.
저작권 © 2023 IDG Communications, Inc.