Skip to main content

Command Palette

Search for a command to run...

EF Core 6 배우기 - 1. 시작하기

Published
4 min read

Entity Framework Core (줄여서 EF Core)는 마이크로소프트에서 개발한 .NET(Core)용 ORM 프레임워크로 Entity Framework의 경험으로 새롭게 재개발 되었습니다. ORM(Object-relational mapping)을 이용하면 SQL 쿼리를 사용하지 않고 DBMS에 종속적인 코드를 최소화 할 수 있습니다.

EF Core 6에 이르러서 데이터베이스를 마이그레이션하기 위한 별도의 실행형 번들을 지원하고 ConfigureConventions() 메소드를 오버라이드 하는 것으로 다양한 관례를 일괄 적용할 수 있는 방법을 제공하며, 컴파일된 모델 지원과 Dapper에 근접한 성능 및 효율적인 SQL 쿼리 생성 등 많은 개선사항이 포함되었습니다. 이제 EF Core를 이용해 EF Core를 지원하는 DBMS를 이용해 ORM을 충분히 현업에서 사용할 수 있습니다.

이번 장은 콘솔 프로젝트에서 EF Core 개발 환경을 구성하는 방법을 설명합니다.

개발 환경

  • Visual Studio 2022
  • .NET 6

EF Core 패키지 추가

NuGet을 이용하면 쉽게 EF Core 패키지를 추가할 수 있습니다.

먼저 적절한 프로젝트 디렉토리에서 콘솔 프로젝트를 생성한 후

dotnet new console

SQLite를 사용하는 구성으로 EF Core 패키지를 추가합니다.

dotnet add package Microsoft.EntityFrameworkCore.Sqlite

Microsoft.EntityFrameworkCore.Sqlite만 추가하면 SQLite를 이용한 EF Core의 패키지가 모두 추가됩니다.

마이그레이션 도구 설치

EF Core로 만든 ORM 모델은 결국 데이터베이스 스키마로 변환 되어야 합니다. EF Core에서 제공하는 dotnet CLI 도구 또는 패키지 관리자 콘솔 도구를 사용할 수 있는데 여기서는 dotnet CLI 도구를 사용하는 방법을 소개합니다.

dotnet tool install 명령을 통해 dotnet-ef 도구를 전역 설치합니다.

dotnet tool install --global dotnet-ef

이후 dotnet tool update로 최신 버젼으로 업데이트 할 수 있습니다.

dotnet tool update --global dotnet-ef

이제 이 도구를 사용할 프로젝트 디렉토리에서 Microsoft.EntityFrameworkCore.Design 패키지를 추가합니다.

dotnet add package Microsoft.EntityFrameworkCore.Design

모델 생성

EF Core의 동작을 빠르게 확인하기 위해 간단한 엔터티를 추가해 보도록 합시다.

| Entities/LogHistory.cs

using System.ComponentModel.DataAnnotations;

namespace EFCoreFirstApp.Entities;
public class LogHistory
{
    [Key]
    public int Seq { get; set; }
    public string Detail { get; set; }
    public DateTime CreateTime { get; set; } = DateTime.Now;

    public LogHistory(string detail)
    {
        Detail = detail;
    }
}

다음으로 DB 컨텍스트를 생성해서 모델을 완성합니다.

| DbContexts/FirstAppContext.cs

using EFCoreFirstApp.Entities;

using Microsoft.EntityFrameworkCore;

namespace EFCoreFirstApp.DbContexts;

public class FirstAppContext : DbContext
{
    public DbSet<LogHistory> LogHistories => Set<LogHistory>();

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        // "database.db" 파일로 SQLite 사용
        optionsBuilder.UseSqlite("Data Source=database.db");
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // LogHistory의 키인 `Seq`는 자동 증가로 설정
        modelBuilder.Entity<LogHistory>()
            .Property(x => x.Seq)
            .ValueGeneratedOnAdd();
    }
}

마이그레이션

EF Core는 도구를 통해 마이그레이션 할 수 있으며 엔터티 및 DB 컨텍스트의 변화를 감지해 변화에 대한 마이그레이션 코드를 자동 생성합니다. 이 정보로 데이터베이스에 업데이트해서 최신의 모델을 데이터베이스 스키마로 적용할 수 있습니다.

| 마이그레이션 추가

dotnet ef migrations add first

dotnet ef migrations add 명령과 first라는 마이그레이션명으로 마이그레이션을 진행했으며 이 명령을 통해 다음의 코드가 자동 생성됩니다.

| Migrations/20220517050233_first.cs

using System;
using Microsoft.EntityFrameworkCore.Migrations;

#nullable disable

namespace EFCoreFirstApp.Migrations
{
    public partial class first : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.CreateTable(
                name: "LogHistories",
                columns: table => new
                {
                    Seq = table.Column<int>(type: "INTEGER", nullable: false)
                        .Annotation("Sqlite:Autoincrement", true),
                    Detail = table.Column<string>(type: "TEXT", nullable: false),
                    CreateTime = table.Column<DateTime>(type: "TEXT", nullable: false)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_LogHistories", x => x.Seq);
                });
        }

        protected override void Down(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.DropTable(
                name: "LogHistories");
        }
    }
}

이 정보를 이용해 데이터베이스 스키마에 적용하려면 다음의 명령을 사용합니다.

dotnet ef database update

명령이 정상 실행되면 프로젝트 디렉토리에 database.db가 생성된 것을 확인할 수 있으며 DB Browser등의 SQLite 클라이언트를 이용해 데이터베이스 스키마가 잘 생성되었음을 확인할 수 있습니다.

image.png

생성된 database.db는 실행경로로 복사해야 동일한 설정 환경에서 테스트가 가능합니다. image.png

코드 작성

생성한 모델을 이용해 정보를 저장하고 조회하는 코드를 작성해봅시다.

using EFCoreFirstApp.DbContexts;
using EFCoreFirstApp.Entities;

using var c = new FirstAppContext();

// 갯수 조회
var count = c.LogHistories.Count();

// 목록 3개 추가
var lastSeq = 0;
for (var i = 0; i < 3; i++)
{
    var newinfo = new LogHistory($"{i + 1}번째 데이터");
    c.LogHistories.Add(newinfo);

    c.SaveChanges();    
    // 저장 후 식별번호 생성됨
    lastSeq = newinfo.Seq;
}

// 목록 조회
foreach (var info in c.LogHistories)
{
    Console.WriteLine($"{info.Seq} : {info.Detail}, {info.CreateTime}");
}

// 추가한 목록 중 마지막 항목 수정
var targetInfo = c.LogHistories.First(x => x.Seq == lastSeq);
targetInfo.Detail += "(수정함)";
c.SaveChanges();

Console.WriteLine();

// 다시 목록 조회
foreach (var info in c.LogHistories)
{
    Console.WriteLine($"{info.Seq} : {info.Detail}, {info.CreateTime}");
}

Console.WriteLine();

// 마지막 항목 삭제
c.LogHistories.Remove(targetInfo);
c.SaveChanges();

// 다시 목록 조회
foreach (var info in c.LogHistories)
{
    Console.WriteLine($"{info.Seq} : {info.Detail}, {info.CreateTime}");
}

| 결과

1 : 1번째 데이터, 2022-05-17 오후 3:15:35
2 : 2번째 데이터, 2022-05-17 오후 3:15:35
3 : 3번째 데이터, 2022-05-17 오후 3:15:35

1 : 1번째 데이터, 2022-05-17 오후 3:15:35
2 : 2번째 데이터, 2022-05-17 오후 3:15:35
3 : 3번째 데이터(수정함), 2022-05-17 오후 3:15:35

1 : 1번째 데이터, 2022-05-17 오후 3:15:35
2 : 2번째 데이터, 2022-05-17 오후 3:15:35

image.png

LINQ 메소드와 항목을 추가하거나 변경하고 삭제하는 동작이 데이터베이스에 반영됨을 확인할 수 있습니다.

소스코드

https://github.com/dimohy/efcore-learning/tree/main/1.%20%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0/EFCoreFirstApp

More from this blog

개발, 테스트, 운영에서의 도커 활용

핵심 원칙: "한 번 빌드하고, 어디서든 실행한다 (Build once, run anywhere)" 도커의 가장 큰 장점은 환경 일관성입니다. 동일한 도커 이미지를 사용하여 개발, 테스트, 운영 환경을 구성함으로써 "제 PC에서는 됐는데..." 하는 문제를 최소화할 수 있습니다. 1. 개발 단계 (Development) 목표: 빠른 코드 변경 반영, 쉬운 디버깅, 실제 운영 환경과 유사한 환경 구성. Docker 사용 방안: Dockerf...

May 9, 20256 min read15

[EF Core] 데이터 삭제 시 소프트 삭제 적용

DB에서 데이터를 삭제하면 일반적으로 복구할 수 없습니다. 또한 관계에 따라 영구 삭제 자체가 어려울 수도 있습니다. 그래서 데이터를 영구 삭제하는 대신 IsDeleted 속성을 true로 주고 IsDeleted 속성을 필터링해서 조회하는 방법을 사용하기도 합니다. 이를 소프트 삭제라고 합니다. 그런데 EF에서 알아서 데이터 삭제 시 소프트 삭제를 하고 쿼리시 IsDeleted 속성을 체크해서 삭제한 데이터를 제외한 데이터만 쿼리하게 하는 ...

Mar 18, 20243 min read19

[EF Core] ValueConverter를 이용해서 엔터티 속성의 도메인 관리

EF Core를 사용하면서 문자열 길이 등의 특성을 일일이 지정하는 것은 번거롭습니다. ... [MaxLength(32)] public string? 제목 { get; set; } 엔터티가 한 개일 때는 상관이 없으나 제목 유형이 여러 엔터티에 사용될 경우 유형을 지정하기 번거롭습니다. 속성 유형을 도메인으로 관리하면 참 편할텐데요, ValueConverter를 이용할 수 있습니다. 그런데 이것을 인터페이스 정적 추상를 사용해서 다음처럼 ...

Mar 16, 20242 min read8

디모이 블로그

154 posts

.NET 관련 기술을 선호하고 새로운 언어를 배우는데 관심이 있습니다.

EF Core 6 배우기 - 1. 시작하기