[C# 서버] DB - EFC, CRUD

이정석·2023년 9월 4일
0

CSharpServer

목록 보기
12/13
post-thumbnail

Entity Framework Core

Entity Framework Core(EFC)는 .NET Core.NET 5버전 이상에서 사용가능한 ORM 프레임워크로 코드로 데이터베이스 생성, 테이블 생성과 같은 데이터베이스 작업을 수행할 수 있다. 이 외에도 DB Migration으로 데이터베이스 스키마를 버전 관리할 수 있다.

EFC를 C#프로젝트에서 사용하기 위해 NuGet패키지 관리자로 아래 사진과 같은 패키지를 설치해야 한다.

1. Entity 정의

데이터베이스에서 Table이 될 Entity를 하나의 클래스로 나타낼 수 있다. [Table("Item")]와 같은 어트리뷰트로 데이터베이스가 생성될 때의 테이블 이름을 지정할 수 있으며 Entity간의 참조형식도 지정할 수 있다.

    [Table("Item")]
    public class Item
    {
        public int ItemId { get; set; }
        public int TemplateId { get; set; }
        public DateTime CreateData { get; set; }

        public int OwnerId { get; set; }
        public Player Owner { get; set; }
    }

    public class Player
    {
        public int PlayerId { get; set; }
        public string Name { get; set; }
    }

public int 클래스이름+Id형식의 컬럼은 해당 테이블의 PK(Primary Key)로 설정된다. 또한 Item을 보면 Item은 Owner라는 이름으로 Player Entity를 참조하고 public int OwnerId라는 프로퍼티가 있으므로 OwnerId는 FK(Foreign Key)로 설정된다.

2. DbContext 정의

실제 코드에서 데이터베이스를 사용하기 위한 클래스는 DbContext를 상속받아 해당 클래스를 사용해 코드에서 테이블로 접근할 수 있다.

DbSet<Item>은 외부에서 테이블을 접근하기 위한 수단을 제공하며 OnConfiguring와 같은 On계열 함수는 데이터베이스 연결, 데이터베이스 생성, 데이터베이스 모델생성 단계에서 추가적으로 설정하고자 하는 내용을 반영할 수 있도록 한다.

    public class AppDbContext : DbContext
    {
        public DbSet<Item> Items { get; set; }

        public const string connectionString = "";

        protected override void OnConfiguring(DbContextOptionsBuilder options)
        {
            options.UseSqlServer(connectionString);
        }
    }
  • OnModelCreating: 데이터베이스 모델이 생성되는 단계에 호출되는 함수로 테이블 이름이나 복합키, 인덱스와 같은 테이블 설정을 할 수 있다.

CRUD

EFC를 이용해 특정 Entity에 대한 CRUD를 구현할 수 있다. 이때 데이터베이스의 테이블에 질의한 결과를 얻기 위해서는 앞서 정의한 DbContext의 하위클래스의 DbSet을 통해 할 수 있다.

1. Create

Create연산은 생성하고자 하는 Entity 클래스를 생성한 뒤 DbContext의 Add함수로 추가할 수 있다.

    using (var db = new AppDbContext())
    {
        var player = new Player { Name = "Seoki" };
        db.Add(player);
        db.SaveChanges();
    }

여러개의 Entity를 추가하기 위해서는 AddRange를 사용할 수 있다.

2. Read

Read연산은 Where함수를 통해 특정 조건을 만족하는 데이터를 필터링할 수 있고 매개변수로는 조건에 해당하는 LINQ 쿼리를 넣어주어야 한다.

    using (var db = new AppDbContext())
    {
        var items = db.Items
                        .Where(i => i.OwnerId == player.PlayerId)
                        .ToList();

        foreach (var item in items)
        {
            Console.WriteLine($"{item.ItemId}");
        }
    }

PK를 이용해 단일 Entity를 검색할 때는 Find함수를, LINQ 쿼를 이용해 단일 Entity를 검색할 때는 Single, First를 사용할 수 있다.

3. Update

Update는 찾은 Entity의 값을 변경한 뒤 SaveChange를 통해 데이터베이스로 변경사항을 적용함으로 구현할 수 있다.

    string name = "Seoki";
    
    using (var db = new AppDbContext())
    {
        var items = db.Items.Include(i => i.Owner)
                .Where(i => i.Owner.Name == name);

        foreach(Item item in items)
        {
            item.CreateData = DateTime.Now;
        }

        db.SaveChanges();
    }

Update과정에서 사용한 Include는 Entity구조의 Item에서 참조하는 Player의 값을 가져오기 위한 함수이다.

공식문서를 찾아보니 Include는 EFC에서 Navigation Property를 로딩하기 위한 함수라고 한다. 이것은 'Eager Loading'이라고 하며 이를 통해 N+1문제를 방지할 수 있다.

4. Delete

Delete는 찾은 Entity를 DbContext의 Remove함수의 인자로 넘겨 해당 데이터를 삭제하겠다는 사항을 알리고 SaveChanges를 이용해 데이터베이스에 반영하는 방법으로 구현할 수 있다.

    string name = "Seoki";

    using (var db = new AppDbContext())
    {
        var items = db.Items.Include(i => i.Owner)
                .Where(i => i.Owner.Name == name);

        db.Items.RemoveRange(items);

        db.SaveChanges();
    }

Delete 역시 여러개의 데이터를 삭제하려면 RemoveRange함수를 사용할 수 있다.

profile
게임 개발자가 되고 싶은 한 소?년

0개의 댓글