[EF Core] EF Core & PostgreSQL Column JSONB 타입 데이터 추가

참고


목적

  • PostgreSQL 에서는 Column Type 중에 JSONB 라는 타입이 있습니다.
  • JSONB 타입의 컬럼을 EF Core 로 생성하여, 실제로 JSONB 형태로 데이터 저장 가능한지 테스트 진행합니다.

개발 환경

  • 개발 환경은 다음과 같습니다.
    • OS : Windows 10
    • .NET Version : .NET 6
    • IDE : Visual Studio 2022
    • Database : PostgreSQL

콘솔 프로그램 생성

  • Visual Studio 2022 실행하여, .NET 6 버전으로 콘솔 프로젝트 하나를 생성합니다.
  • 저는 EFCoreSample 이라는 이름으로 프로젝트 생성 하였습니다.


클래스 라이브러리 생성

  • 다음으로, EF Core 기능 및 Entity 관리를 위하여 클래스 라이브러리 하나를 생성합니다.
  • 이름은 InferenceApp.Data 라고 하였습니다.


프로젝트 참조하기

  • 앞에서 콘솔 프로젝트와 클래스 라이브러리를 생성하였습니다.
  • 클래스 라이브러리의 역할은 EF Core 관련 내용들입니다.
  • 때문에, 콘솔 프로젝트에 클래스 라이브러리를 참조해 줍니다.

EF Core 관련 NuGet Package 추가

  • 앞서, 클래스 라이브러리를 생성 완료하였다면 EF Core 관련한 NuGet Package 를 추가해야 합니다.
  • 추가해야 하는 NuGet Package 는 다음과 같습니다.
    • Micorsoft.EntityFrameworkCore.Tools
    • Npgsql.EntityFrameworkCore.PostgreSQL
  • 위 2개의 NuGet Package 를 설치 진행합니다.


Entity 관련 클래스 추가

  • 다음으로 클래스 라이브러리에서 Entity 관련 클래스를 추가해야 합니다.
  • Inference.cs 하나를 생성한 후, 아래와 같이 코드를 작성하였습니다.
  • 아래 테이블의 관계는 Inspection 테이블Inference 테이블1:N 관계 를 보여 주고 있습니다.
  • 또한 Inference 테이블 속성 중, Defects 속성의 타입을 Annotaion 표기법으로 jsonb 라고 명시 하였습니다.
  • 이 말은 즉, Defects 속성에 데이터가 추가할 때 JSONB 타입으로 데이터가 저장된다는 이야기입니다.
  • Defect 클래스는 JSONB 타입으로 데이터를 저장하기 위한 클래스입니다.
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace InferenceApp.Data
{
    public class Inspection
    {
        [Key]
        public int INDEX { get; set; }  
        public string LOT_ID { get; set; }  
        public string DEVICE_ID { get; set; }   
        public List<Inference> Inferences { get; set; }  
    }

    public class Inference
    {
        [Key]
        public int INDEX { get; set; }
        public int INSPECTION_INDEX { get; set; }   
        public bool INFER_ONLY { get; set; }
        [Column(TypeName = "jsonb")]
        public Defect[] Defects { get; set; }
        public Inspection Inspection { get; set; }
    }

    public class Defect
    {
        public string DefectID { get; set; }    
        public string ResultValue { get; set; }
    }
}

  • 다음으로 InferenceContext.cs 클래스를 선언하여, EF Core 마이그레이션에 필요한 내용을 C# 코드로 작성합니다.
  • 다음 코드에서 OnModelCreating 메서드 안에서 Fluent API 방식으로 현재 1:N 관계를 표현하고 있습니다.
using Microsoft.EntityFrameworkCore;

namespace InferenceApp.Data
{
    public class InferenceContext : DbContext
    {
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseNpgsql(@"Server=localhost;Database=JoBeomHee;Port=5432;User Id=JoBeomHee;Password=1234");
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Inference>()
                .HasOne<Inspection>(i => i.Inspection)
                .WithMany(i => i.Inferences)
                .HasForeignKey(i => i.INSPECTION_INDEX);
        }

        public DbSet<Inspection> inspections { get; set; }  
        public DbSet<Inference> inferences { get; set; }    
    }
}

마이그레이션 작업

  • 이제 마이그레이션 작업을 위한 선행 작업을 모두 마쳤습니다.
  • 도구 -> NuGet Package Manaegr -> NuGet 콘솔 프로그램 을 실행하여 아래와 같은 명령어를 작성하여 실행합니다.
> Add-Migration InitialDatabase
  • 위 명령어가 정상적으로 실행 되었다면, Migration 이라는 폴더가 생성된 것을 확인할 수 있습니다.

  • 다음으로 Update-Database 명령어를 실행해 줍니다.
  • 해당 명령어까지 실행 되어야, 실제 데이터베이스까지 마이그레이션 작업이 모두 적용됩니다.
> Update-Database
  • 실행 결과, PostgreSQL 데이터베이스에 Inspections, Inferences 2개의 테이블이 생성된 것을 확인할 수 있습니다.
  • 또한, Inferences 테이블에서 Defects 컬럼의 타입이 JSONB 타입으로 생성된 것도 확인할 수 있습니다.


데이터 추가

  • 마이그레이션 작업이 모두 완료 되었습니다.
  • 이제 실제로 해당 테이블에 데이터를 삽입해 보도록 하겠습니다.
  • 앞서 생성했던 콘솔 프로그램의 Program.cs 에 다음과 같이 코드를 추가합니다.
  • 아래 코드는 10개의 Inspection 데이터를 저장하고, Inference 데이터에서 Defect 은 총 10000개로 하여 JSONB 형태로 정상적으로 데이터가 저장되는지 확인하는 코드입니다.
using InferenceApp.Data;

using (var context = new InferenceContext())
{
    context.Database.EnsureCreated();
    AddInspectionData(context);
}

static void AddInspectionData(InferenceContext context)
{
    for(int index = 1; index <= 10; index++)
    {
        context.inspections.Add(new Inspection
        {
            INDEX = index,
            LOT_ID = $"LOT_ID_{index}",
            DEVICE_ID = $"ATI_{index}",    
        });

        context.SaveChanges();

        AddInferenceData(context, index);
    }
}

static void AddInferenceData(InferenceContext context, int inspection_index)
{
    Defect[] dft_list = new Defect[10000];
    for(int index = 0; index < 10000; index++)
    {
        dft_list[index] = new Defect() { DefectID = index.ToString(), ResultValue = index.ToString() };
    }

    Inference infer = new()
    {
        INDEX = inspection_index,
        INSPECTION_INDEX = inspection_index,
        INFER_ONLY = true,
        Defects = dft_list
    };

    context.inferences.Add(infer);

    context.SaveChanges();
}

Inspections 테이블

  • 실행 결과, 총 10개의 데이터가 Inspection 테이블에 정상적으로 저장된 것을 확인할 수 있습니다.


Inferences 테이블

  • 실행 결과, 총 10개의 데이터가 Inferences 테이블에 저장이 되었고, Defects 컬럼에는 각 데이터당 10000개의 Defect 정보들이 JSONB 형태로 저장된 것을 확인할 수 있습니다.

728x90

이 글을 공유하기

댓글

Designed by JB FACTORY