-
EF Core 시작하기(1) - ef core 패키지 설치, DB 연결.NET/Database 2023. 12. 17. 06:16
EF Core
EF Core는 닷넷의 ORM도구인 Entity Framework를 오픈 소스 플랫폼 교차 버전으로 만든 것 입니다.
Entity Framework가 visual studio 환경에 종속적이고 GUI환경에 윈도우창으로 나오는 설계 도구를 사용해서 사용했다면,
EF Core는 Cli기반이므로 Visual sutdio를 사용할 수 없는 리눅스나, 맥에서도 터미널을 통해서 사용할 수 있습니다.이 포스트에서는 DBMS로 MySql을 사용하고 있고, docker를 이용해서 로컬에 설치하고 진행했습니다.
IDE는 Rider를 사용하였습니다. 맥이나 리눅스에서도 동일하게 사용할 수 있습니다.
이부분은 포스트에서는 생략합니다.dotnet tool 설정
dotnet sdk가 설치되어 있다면 터미널에서
dotnet tool install --global dotnet-ef
를 진행해서 dotnet-ef cli도구를 설치해주세요
이렇게 설치된 툴은
dotnet tool list --global
명령을 통해서 정상적으로 설치되었는지 확인이 가능합니다.
프로젝트 생성
설치를 확인했으면 ide에서 프로젝트를 생성해주세요
저는 .NET8 버전 Console Application으로 프로젝트를 생성했습니다.
EF Core 필요한 nuget package 설치
EF Core의 기능들을 사용하기 위해선 몇가지 패키지가 필요합니다.
Microsoft.EntityFrameworkCore - EF Core 핵심패키지입니다.
Microsoft.EntityFrameworkCore.Design - Database Migration에 필요한 패키지입니다.
Microsoft.EntityFrameworkCore.Tools - Cli도구와 통합된 EF Core 관련작업을 도와주는 도구입니다. Scaffold와 Migration 버전관리시 필요합니다.
그리고 EF Core Provider 패키지가 필요한데 이것은 실질적으로 쿼리를 만들어주는 역할을 하는 패키지들이기 때문에
DBMS별로 사용해야하는 패키지가 다릅니다.
Database Providers - EF Core | Microsoft Learn
Database Providers - EF Core
Information about specific supported Entity Framework Core providers and about providers in general
learn.microsoft.com
DBMS별로 Provider를 어떤것을 사용하면 되는지 나와있는 페이지입니다. 이페이지를 참고해서 사용하시면 됩니다.
저는 MySql을 사용할 것이므로 Pomelo.EntityFrameworkCore.MySql을 설치하도록 하겠습니다.
프로젝트의 Dependencies를 우클릭해서
nuget package manager를 이용해서 다운받거나
터미널을 실행시키고 프로젝트 루트(.csproj 파일이 있는 경로)에서 다음 명령어를 실행합니다.
dotnet add package Microsoft.EntityFrameworkCore --version 7.0.14 dotnet add package Microsoft.EntityFrameworkCore.Design --version 7.0.14 dotnet add package Microsoft.EntityFrameworkCore.Tools --version 7.0.14 dotnet add package Pomelo.EntityFrameworkCore.MySql --version 7.0.0
* 현재 최신버전은 8.0이나 아직 Pomelo MySql Provider가 8.0버전이 베타이므로
7.0 기준으로 진행합니다. 추후에 8.0이 정식 릴리즈가 되더라도, 본 포스트와 다른점은 없을 것으로 생각합니다.
Connection String
데이터를 연결하기 위한 커넥션 스트링 입니다.
server=127.0.0.1;port=3306;user=root;password=dlwhdgns; database=BBS;
Scaffold (Database First)
스캐폴드는 데이터베이스가 이미 있는 상태에서 코드에 테이블/뷰과 같은 스키마를 C# 코드로 옮기는 작업입니다.
ef powertool과 같은 vs extension을 사용하면 좀더 편하게 작업이 가능합니다.
우선 데이터베이스에 테이블가 먼저 생성되어 있어야하므로 아래와 같이 테이블을 생성해주세요.
데이터베이스 구성
CREATE TABLE `USERS` ( `UserId` INT AUTO_INCREMENT PRIMARY KEY, `UserName` VARCHAR(50) NOT NULL, `EMail` VARCHAR(100) ); CREATE TABLE `BOARD` ( `BoardId` INT AUTO_INCREMENT PRIMARY KEY, `Title` VARCHAR(100) NOT NULL, `Contents` TEXT NOT NULL, `PostDate` DATETIME DEFAULT CURRENT_TIMESTAMP, `UserId` INT, FOREIGN KEY (`userId`) REFERENCES `USERS`(`userId`) );
정상적으로 생성을 했다면 프로젝트 루트에서 다음과 같은 명령을 실행시킵니다.
dotnet ef dbcontext scaffold "server=127.0.0.1;port=3306;user=root;password=dlwhdgns; database=BBS;" Pomelo.EntityFrameworkCore.MySql
옵션을 넣지않고 스캐폴드 하게되면 이렇게 실행 디렉토리에 엔터티 클래스파일과 DbContext 파일 또한 여기에 생성됩니다.
어떤 옵션이 있는지 보려면 다음과 같이 실행시키면 Scaffold의 옵션들을 볼수 있습니다.
dotnet ef dbcontext scaffold -h
저는 여기서 context 파일의 위치를 지정하는 옵션, entity파일의 위치를 지정하는 옵션 , 덮어쓰기 옵션, context에서 onconfiguring 코드를 자동생성하지 않도록 설정하는 옵션등을 지정했습니다.
dotnet ef dbcontext scaffold "server=127.0.0.1;port=3306;user=root;password=dlwhdgns; database=BBS;" Pomelo.EntityFrameworkCore.MySql --context-dir context --output-dir models --force --no-onconfiguring
이렇게 하고나면 좀더 깔끔하게 파일위치를 지정할 수 있습니다.
생성된 클래스 확인 (Database Context )
스캐폴드에서는 내 데이터베이스에 접근하는 DbContext를 상속받아 설정하는 코드가 생성됩니다.
BbsContext라는 명칭의 클래스가 DbContext를 상속받아 생성된것을 볼수있습니다. 기본생성자는 위와같고 만약 --no-onconfiguring 옵션을 넣지 않았다면 ConnectionString이 하드코딩되어있는 OnConfiguring까지 생성되게 됩니다.
만약 스캐폴드 형식으로 프로젝트를 사용하신다면 이 BbsContext.cs 파일은 테이블이 생성되거나 할때 많이 바뀔것입니다.
그래서 partial class로 생성되어 있는 것이고 별도의 내용을 넣는다면 이파일에 직접 넣기보다는 partial을 이용해서 다른 파일에 작업해주시는게 편합니다.
modelBuilder.Entity<Board>(entity => { entity.HasKey(e => e.BoardId).HasName("PRIMARY"); entity.ToTable("BOARD"); entity.HasIndex(e => e.UserId, "UserId"); entity.Property(e => e.Contents).HasColumnType("text"); entity.Property(e => e.PostDate) .HasDefaultValueSql("CURRENT_TIMESTAMP") .HasColumnType("datetime"); entity.Property(e => e.Title).HasMaxLength(100); entity.HasOne(d => d.User).WithMany(p => p.Boards) .HasForeignKey(d => d.UserId) .HasConstraintName("BOARD_ibfk_1"); });
OnModelCreating 메서드는 데이터베이스 컨텍스트의 모델 구성을 커스터마이즈하는 데 사용됩니다.
데이터베이스에서 어떤 charset을 쓸지, 어떤 엔터티클래스가 어떤 테이블을 사용하게 할지 등을 설정합니다.
확장메서드로 HasKey(), HasName() 등으로 정의되어 있는 것들을 보면 테이블 구성이 어떻게 되있는지 코드상에 정의되어있다는 것을 알수 있습니다.
이런식으로 정의하는 것은 Fluent API라고 합니다.
Fluent API Configuration (learnentityframeworkcore.com)
fluent api에 대해서는 위 페이지에서 더 자세히 확인 가능합니다.
생성된 클래스 확인 (Entity Class)
자동생성된 두개의 클래스를 보면
Board클래스의 외래키로 Userid가 지정되어 있기때문에 virtual User? User 멤버가 포함되어 있습니다.
그럼 Baord 테이블을 Select 하면 User 테이블까지 가져오는게 아닌가 하는 의심이 드실수 있지만 그건 아닙니다.
User클래스에는 마찬가지로 ICollection<Board> Boards 가 멤버로 포함되어 있습니다.
스캐폴딩(리버스 엔지니어링)에 대한 내용은 아래 페이지에서 더 자세하게 확인 할 수 있습니다.
리버스 엔지니어링 - EF Core | Microsoft Learn
Migration (Code First)
스캐폴드는 DB 스키마에서 C#코드를 생성했다면
마이그레이션은 반대로 C#코드를 바탕으로 DB에 적용합니다.
그에 따라서 DBA 담당 없이 개발해야하는 환경이라면,
코드베이스로 DB까지 관리하기가 좋습니다.
확인을 위해서 기존의 DB의 테이블을 모두 지워주세요
public class BbsContext : DbContext { protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseMySql("server=127.0.0.1;port=3306;user=root;password=dlwhdgns;database=BBS", new MySqlServerVersion(new Version(8, 1, 0))); } public virtual DbSet<Board> Boards { get; set; } public virtual DbSet<User> Users { get; set; } }
Db Context를 위와같이 바꿔주세요
Entity Class파일에서는
위와 같이 정의해주시면 됩니다.
스캐폴드로 만들어진 코드와 다른점은 [Attribute]로 Key를 지정해 줬다는 것을 볼 수 있습니다.
이부분은 개발자 선택입니다. Attribute로 지정하거나 FluentApi로 지정할수 있다는 점을 알아두시고
필요따라 선택하셔서 하시면 됩니다.
그리고 마찬가지로 project root디렉토리에서 다음 커맨드를 실행합니다.
dotnet ef migrations add InitialCreate dotnet ef database update
커맨드를 실행하고 나면
Migrations 폴더가 생성되고 그안에 현재 코드로 작성된 내용을 바탕으로
db구성을 어떻게 하였는지에 대한 내용을 저장합니다.
database update를 하는 순간 Database에 반영됩니다.
그리고 __EFMigrationsHistory라는 테이블은 지정하지 않았음에도 추가되는데 여기에 마이그레이션 한 이력정보들이 나오게됩니다.
자동으로 생성된 엔터티들은 DbContext나 Attribute로 테이블에 대한 상세한 내용을 지정하지 않았기때문에
테이블명은 자동으로 Boards 로 복수형명칭으로 생성되었고,
각 컬럼도 상세하게 지정하지 않았기때문에 자동으로 longtext 등으로 지정되었습니다.
연결에 대한 내용은 여기까지 하고
다음 포스트에서는 Dependency Injection을 하고 CRUD를 하는 내용을 다뤄보겠습니다.
'.NET > Database' 카테고리의 다른 글
EF Core 테이블 상속 매핑 (TPT) (0) 2025.02.17 EF Core - (부록) Project Setup (0) 2025.02.03 EF Core - Code First (0) 2025.01.11 EF Core - Domain 분리구조 만들기 (0) 2024.03.22 EF Core 시작하기(2) - DI,CRUD (0) 2023.12.22