인프런 커뮤니티 질문&답변

요가인님의 프로필 이미지
요가인

작성한 질문수

[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part8: Entity Framework Core

DB 연결

DB와 연결이 되지 않아 질문 남겨요

작성

·

201

0

먼저

AppDbContext.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;

namespace MMO_EFCore
{
    // EF Core 작동 스텝
    // 1) DB Context 만들 때
    // 2) DbSet<T>을 찾는다
    // 3) 모델링 class 분석해서, 칼럼을 찾는다.
    // 4) 모델링 class에서 참조하는 다른 class가 있으면, 걔도 분석한다.
    // 5) OnModelCreating 함수 호출 (추가 설정 = override)
    // 6) 데이터 베이스의 전체 모델링 구조를 내부 메모리에 들고 있음
    public class AppDbContext : DbContext
    {
        // DbSet<Item> -> EF Core한테 알려준다
        // Item이라는 DB 테이블이 있는데, 세부적인 칼럼/키 정보는 item 클래스를 참고해
        public DbSet<Item> Items { get; set; }

        // DB ConnectionString
        // 어떤 DB를 어떻게 연결해라 (각종 설정, Authorization 등)
        public const string ConnectionString = @"Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=EFCoreDb;Integrated Security=True;Connect Timeout=30;Encrypt=False;Trust Server Certificate=False;Application Intent=ReadWrite;Multi Subnet Failover=False";

        protected override void OnConfiguring(DbContextOptionsBuilder options)
        {
            options.UseSqlServer(ConnectionString);
        }
    }
}

DataModel.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MMO_EFCore
{
    public class Item
    {
        // PK
        public int ItemId { get; set; }
        public int TemplateId { get; set; } // 101 -> 집행검
        public DateTime CreateDate { get; set; }

        // 다른 클래스 참조 -> FK (Navigational Property)
        public int OwnerId { get; set; } 
        public Player Owner { get; set; }
    }

    // 클래스 이름 = 테이블 이름 = Player
    public class Player
    {
        //  이름Id = PK
        public int PlayerId { get; set; }
        public string Name { get; set; }

    }
}

Program.cs

using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage;

namespace MMO_EFCore
{
    internal class Program
    {
        // 초기화 시간 좀 걸림
        static void InitializeDB(bool forceReset = false)
        {
            using (AppDbContext db = new AppDbContext())
            {
                if (forceReset && (db.GetService<IDatabaseCreator>() as RelationalDatabaseCreator).Exists())
                    return;
                 
                db.Database.EnsureDeleted();
                db.Database.EnsureCreated();

                Console.WriteLine("DB Initialized");
            }
        }

        static void Main(string[] args)
        {
            InitializeDB(forceReset: true);
        }
    }
}

SQL Server

연결 문자열

Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=EFCoreDb;Integrated Security=True;Connect Timeout=30;Encrypt=False;Trust Server Certificate=False;Application Intent=ReadWrite;Multi Subnet Failover=False

 

이렇게 되어있는 상태이고

실행시 DB Initialized 출력을 못하고 계속 끝나버리길래

디버그로 확인을 해보니

if (forceReset && (db.GetService<IDatabaseCreator>() as RelationalDatabaseCreator).Exists())
    return;

이 부분에서 if 문에서 걸려서 return 됩니다

 

--> https://stackoverflow.com/questions/33911316/entity-framework-core-how-to-check-if-database-exists
이 사이트와

https://learn.microsoft.com/en-us/ef/core/managing-schemas/ensure-created

이 사이트를 참조 했는데 해결을 못해서 질문 남겨봅니다.

(Microsoft.EntityFrameworkCore.SqlServer 버전 8.0.3)

답변 1

0

안녕하세요, 인프런 AI 인턴입니다. 요가인님의 질문에 대해 답변 드립니다.

질문에서 제시된 코드는 Entity Framework Core를 사용하여 데이터베이스를 초기화하는 부분을 담고 있으며, 코드 실행 시 DB Initialized 출력이 나오지 않고 프로그램이 끝나는 문제를 겪고 계신 것으로 보입니다. 이는 if 조건문에서 return이 실행되기 때문인 것으로 추측됩니다.

if (forceReset && (db.GetService<IDatabaseCreator>() as RelationalDatabaseCreator).Exists())
이 조건문은 forceResettrue이고 데이터베이스가 이미 존재하는 경우를 체크하여 해당 조건이 만족할 경우 함수에서 빠져나오도록 되어 있습니다. 즉, forceReset 플래그가 true로 설정되었지만 데이터베이스가 이미 존재하기 때문에 추가적인 작업 없이 InitializeDB 함수가 종료되는 것으로 보입니다.

다음 단계로 데이터베이스가 실제로 존재하는지 SQL Server Management Studio 혹은 다른 도구를 사용하여 확인해 보시길 바랍니다. 만약 데이터베이스가 실제로 존재하지 않는다면, Exists() 메서드의 동작이 예상과 다르게 작동하고 있는 것일 수 있습니다.

해당 문제를 해결하려면 다음 포인트를 확인해보십시오:

  1. forceReset 플래그 값을 false로 설정 후 다시 시도해보십시오.
  2. SQL Server에 실제로 EFCoreDb 데이터베이스가 생성되어 있는지 확인하십시오.
  3. EnsureDeleted()EnsureCreated() 메서드가 예상대로 동작하는지 로그를 확인하거나 디버깅을 통해 분석하십시오.

참고 사이트를 보신 것처럼, 데이터베이스의 존재 여부를 체크하는 다른 방법들도 있습니다. 예를 들어 Entity Framework Core: How to check if database exists에서는 IDatabaseCreator 인터페이스를 잘 활용하는 방법이 소개되어 있습니다.

예시가 조금 다르지만 유사한 문제를 겪고 계신 다른 사용자의 질문과 답변을 찾았습니다. 이 링크가 문제 해결에 도움이 될 수 있습니다:

위 링크에서는 DbContextOptionsBuilder와 관련된 부분과 EF Core 버전 호환성 등의 주제로 질문이 이루어졌습니다. 이런 사례들을 참조하여 이슈를 해결하는 데 도움이 될 수 있을 것입니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

요가인님의 프로필 이미지
요가인
질문자

1번 방법대로 forceReset 을 false로 하면 작동이 되는데

궁금한점이 (db.GetService<IDatabaseCreator>() as RelationalDatabaseCreator).Exists() 이 부분이 계속 true란 건데 왜 그런가요 ???

그리고 23분에 [Table("Item")]으로 갱신할 떄는 왜 return이 되지 않는건가요???

요가인님의 프로필 이미지
요가인

작성한 질문수

질문하기