ASP.NET Core에서 Dapper를 사용하여 개체 관계를 매핑하는 방법

CChatGPT8
10 Min Read


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 프로젝트를 만들어 보겠습니다. 다음 단계를 따르세요.

  1. Visual Studio 2022 IDE를 실행합니다.
  2. “새 프로젝트 만들기”를 클릭하세요.
  3. “새 프로젝트 만들기” 창에 표시된 템플릿 목록에서 “ASP.NET Core Web API”를 선택합니다.
  4. 다음을 클릭하세요.
  5. “새 프로젝트 구성” 창에서 새 프로젝트의 이름과 위치를 지정합니다.
  6. 선택적으로 기본 설정에 따라 “동일한 디렉터리에 솔루션과 프로젝트 배치” 확인란을 선택합니다.
  7. 다음을 클릭하세요.
  8. 다음에 표시되는 “추가 정보” 창에서 “컨트롤러 사용(최소 API를 사용하려면 선택 취소)” 확인란을 선택된 상태로 둡니다. 이 프로젝트에서는 최소한의 API를 사용하지 않습니다. “인증 유형”을 “없음”(기본값)으로 설정해 둡니다.
  9. “Open API 지원 활성화”, “HTTPS 구성” 및 “Docker 활성화” 확인란이 선택 해제되어 있는지 확인하세요. 여기서는 이러한 기능을 사용하지 않을 것입니다.
  10. 생성을 클릭합니다.

이 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.

Share this Article
Leave a comment

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다