프로그래밍

[EFCore] Entity Framework Core

Victory_HA 2024. 11. 29. 15:37

Entity Framework Core란?

  • EF Core(Entity Framework Core)는 .NET 애플리케이션에서 데이터베이스와 상호 작용하기 위한 ORM(Object-Relational Mapping) 프레임워크입니다.
  • EF Core는 C# 같은 객체 지향 언어의 클래스를 데이터베이스 테이블과 매핑하여, SQL 쿼리를 작성하지 않고도 데이터베이스 작업을 수행할 수 있도록 도와줍니다.
  • https://learn.microsoft.com/ko-kr/ef/core/

Model이란?

  • EF Core에서는 데이터 액세스가 모델을 통해 수행됩니다.
  • 모델은 엔터티 클래스 및 데이터베이스와의 세션을 나타내는 컨텍스트 개체로 구성됩니다.
  • 컨텍스트 개체를 사용하여 데이터를 쿼리하고 저장할 수 있습니다.

마이그레이션(Migration)이란?

  • 마이그레이션(Migration)은 데이터베이스 스키마(테이블 구조, 열, 키 등)의 변경 사항을 코드로 관리하고, 이를 데이터베이스에 적용하거나 되돌릴 수 있도록 하는 기술입니다.
  • 주로 Entity Framework Core (EF Core)에서 사용되며, 데이터베이스와 애플리케이션 코드 간의 동기화를 쉽게 관리할 수 있도록 도와줍니다.

마이그레이션의 주요 명령어

  • 마이그레이션 추가
    • 현재 모델과 기존 데이터베이스 간의 변경 사항을 기반으로 새로운 마이그레이션 파일을 생성
    • Add-Migrations {MigrationName}
  • 데이터베이스 업데이트
    • 마이그레이션 파일에 기록된 변경 사항을 실제 데이터베이스에 적용
    • Update-Database
  • 마이그레이션 제거
    • 마지막으로 생성된 마이그레이션 파일을 제거
    • Remove-Migration
  • 특정 마이그레이션으로 되돌리기
    • Update-Database {MigrationName}

마이그레이션 파일

  • 마이그레이션 파일은 EF Core가 자동 생성하며,
  • 데이터베이스 변경 사항을 관리하는 두 가지 주요 메서드를 포함합니다
  • Up 메서드:
    • 데이터베이스 스키마를 변경(추가, 수정, 삭제)하는 명령을 정의합니다.
    • 예: 테이블 추가, 열 추가, 관계 정의.
  • Down 메서드:
    • Up 메서드의 변경 사항을 되돌리는 명령을 정의합니다.
    • 예: 테이블 삭제, 열 삭제 등.

마이그레이션의 실무 적용 예

  • 새 테이블 추가

    • 모델 클래스에 새 엔터티 추가

      public class Product
      {
        public int Id { get; set; }
        public string Name { get; set; }
        public decimal Price { get; set; }
      }
    • DbContext에 테이블 추가

      public DbSet<Product> Products { get; set; }
    • 마이그레이션 명령 실행 (visualstudio)

      Add-Migration AddProductTable
      Update-Database
  • 컬럼 수정

    • 모델에서 열 속성 변경

      //public string Name { get; set; }    //AS-IS    
      public string Name { get; set; } = string.Empty;  // 추가된 기본값
    • 마이그레이션 명령 실행 (visualstudio)

      Add-Migration UpdateProductName
      Update-Database

Hands-On

nuget packages

  • Microsoft.EntityFrameworkCore
  • Microsoft.EntityFrameworkCore.SqlServer
  • Microsoft.EntityFrameworkCore.Design
  • Microsoft.EntityFrameworkCore.Tools

SampleCode

Program.cs


 static void Main(string[] args)
 {
     AddDbDatas();
     GetDatas();
 }

private static void AddDbDatas()
{
    using ContosoPizzaContext context = new ContosoPizzaContext();

    Product veggieSpecial = new Product()
    {
        Name = "veggie pizza",
        Price = 9.99M
    };
    context.Products.Add(veggieSpecial);    //Product Dbset에 추가 함

    Product deluxeMeat = new Product()
    {
        Name = "meat",
        Price = 7.77M
    };

    context.Add(deluxeMeat);    //data type을 기준으로 Product Dbset에 자동으로 추가 함
    context.SaveChanges();      //db change
}

private static void GetDatas()
{
    using ContosoPizzaContext context = new ContosoPizzaContext();

    var data = context.Products.Where(p => p.Price > 9.00M).FirstOrDefault();

    if (data is Product)
    {
        data.Price = 12.99M;
    }

    //context.Remove(data);       //delete element
    context.SaveChanges();      //update data
}

ContosoPizzaContext.cs

using EFCore.Models;
using Microsoft.EntityFrameworkCore;

namespace EFCore.Data
{
    public class ContosoPizzaContext : DbContext     //dbcontext는 db내의 세션을 나타내는 것으로 생각하라.
    {
        //아래 4개의 Dbset은 DB에 생성될 테이블에 매핑된다.

        public DbSet<Customer> Customer { get; set; } = null!;
        public DbSet<Order> Order { get; set; } = null!;
        public DbSet<Product> Products { get; set; } = null!;
        public DbSet<OrderDetail> OrderDetails { get; set; } = null!;

        //ontosoPizzaContext가 생성될 때, OnConfiguring 메서드가 호출됩니다.
        //OnConfiguring 메서드는 SQL Server를 사용하고, 지정된 연결 문자열을 통해 데이터베이스와 통신하도록 DbContext를 구성합니다.
        //이후 EF Core는 설정된 환경을 기반으로 LINQ 쿼리나 SaveChanges와 같은 작업을 수행할 수 있습니다.
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)   //EF Core가 데이터베이스에 연결할 때 필요한 옵션(예: 연결 문자열, 데이터베이스 제공자)을 지정합니다.
        {
            optionsBuilder.UseSqlServer(@"Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=ContosoPizza-Part1;Integrated Security=True;");
        }
    }
}

Customer.cs

namespace EFCore.Models
{
    public class Customer
    {
        public int Id { get; set; }
        public string FirstName { get; set; } = null!;
        public string LastName { get; set; } = null!;
        public string? Address { get; set; }
        public string? Phone { get; set; }
        public string? Email { get; set; }
        public ICollection<Order> Orders { get; set; } = null!;
    }
}

Order.cs

namespace EFCore.Models
{
    public class Order
    {
        public int Id { get; set; }
        public DateTime OrderPlaced{get; set; }
        public DateTime? OrderFulfilled{get; set; }
        public int CustomerId{get;set; }
        public Customer Customer { get; set; } = null!;

        public ICollection<OrderDetail> OrderDetails { get; set; } = null!;
    }
}

OrderDetail.cs

namespace EFCore.Models
{
    public class OrderDetail
    {
        public int Id { get; set; }
        public int Quantity { get; set; }
        public int ProductId { get; set; }
        public int OrderId { get; set; }
        public Order Order { get; set; } = null!;
        public Product Product { get; set; } = null!;
    }
}

Product.cs

using System.ComponentModel.DataAnnotations.Schema;

namespace EFCore.Models
{
    public class Product
    {
        public int Id { get; set; }     //pkey
        public string Name { get; set; } = null!;   //.Net 6에서 참조형식에 null을 기본적으로 허용한다.

        [Column(TypeName = "decimal(6,2)")]
        public decimal Price { get; set; }
    }
}

참고자료

'프로그래밍' 카테고리의 다른 글

클래스 간의 관계 (UML)  (0) 2024.12.06
Hypervisor (하이퍼바이저)  (1) 2024.11.28
[Git] 용량이 큰 파일 Push하기 - LFS  (0) 2024.09.05
[VisualStudioCode] SSH 원격접속 오류  (1) 2024.04.26
[Tensorflow] TF.Function  (0) 2024.02.20