ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • EF Core 시작하기(2) - DI,CRUD
    .NET/Database 2023. 12. 22. 00:11

    이전글

    EF Core 시작하기(1) - ef core 패키지 설치, DB 연결 — 개발블로그 (tistory.com)

     

    EF Core 시작하기(1) - ef core 패키지 설치, DB 연결

    EF Core EF Core는 닷넷의 ORM도구인 Entity Framework를 오픈 소스 플랫폼 교차 버전으로 만든 것 입니다. Entity Framework가 visual studio 환경에 종속적이고 GUI환경에 윈도우창으로 나오는 설계 도구를 사용해

    devman-hoon.tistory.com

    이전 포스트에서는 패키지를 설치하고 연결하는데까지 다뤘습니다.

    본격적으로 데이터를 다루는 내용을 하기전에 의존성 주입에 대한 내용이 필요할 것 같습니다.

     

    닷넷 DI도구 패키지를 우선 넣어줍니다.

    ASP.NET Web 프로젝트로 시작하셨다면 이런 도구들은 이미 들어있으니 생략하셔도 됩니다.

    이 시리즈는 콘솔 프로젝트로 진행을 하고 있습니다.

    dotnet add package Microsoft.Extensions.DependencyInjection --version 8.0.0
     

     

     

    이전 포스트에서 만들어진 BbsContext를 주입합니다.

    using EFSampleProject.context;
    using Microsoft.Extensions.DependencyInjection;
    
    var collection = new ServiceCollection();
    collection.AddDbContext<BbsContext>();

    Program.cs의 코드를 위와같이 변경합니다. 

    다른 클래스에서 BbsContext를 주입받아 사용할 준비가 됐습니다.

     

    그리고 기능에 대한 부분을 넣기위해 UserService클래스와 BoardService 클래스를 만들고 다음과 같이 주입해주세요

    using EFSampleProject.context;
    using EFSampleProject.services;
    using Microsoft.Extensions.DependencyInjection;
    
    var collection = new ServiceCollection();
    collection.AddDbContext<BbsContext>();
    collection.AddTransient<UserService>();
    collection.AddTransient<BoardService>();
    var serviceProvider = collection.BuildServiceProvider();

     

    Insert 

    유저 등록 기능을 만들어 봅시다. 

    using EFSampleProject.context;
    using EFSampleProject.models;
    
    namespace EFSampleProject.services;
    
    public class UserService
    {
        private readonly BbsContext _dbContext;
    
        public UserService(BbsContext dbContext)
        {
            _dbContext = dbContext;
        }
    
        public void AddUser(String userName, string userEmail)
        {
            _dbContext.Users.Add(new()
            {
                UserName = userName,
                Email = userEmail,
            });
            _dbContext.SaveChanges();
        }
    }

    UserService의 생성자에서 BbsContext를 받아서 사용하도록 설정합니다.

    위 DI내용에서 BbsContext에 대한 부분을 주입했기 때문에 ServiceProvider를 이용해서 UserService를 생성하는 경우에는 자동으로 BbsContext가 주입됩니다.

     

    이렇게 BbsContext 멤버중 DbSet<T>의 타입을 가진 변수는 테이블과 연결되므로 위와같이 컬렉션에 Add를 하듯이 

    데이터를 넣어주면 됩니다.

     

    Add를 한다고 바로 Database에 적용되는 것이 아니라 SaveChanges()를 해야만 적용이 됩니다.

    RawQuery를 이용한 변환이 아닌경우에는 SaveChanges()까지 해야적용되고, 

    SaveChangesAsync()라는 메서드로 비동기사용이 가능합니다.

    Select

    UserService에 이름을 Select해서 User를 가져오는 기능과, 전체 User를 가져오는 내용을 작성합니다.

    public List<User> GetUsersAll()=>
        _dbContext.Users.ToList();
    
    public List<User> GetUser(string user)
        => _dbContext.Users.Where(x => x.UserName == user).ToList();

    _dbContext.Users 의 타입은 무엇일까요? 

    IQueryable<User> 라는 타입이 됩니다. 해당 타입은 ef core 등에서 쿼리를 지정하여 로우를 받을때 지금 당장 해당 쿼리를 실행하지 않고 ToList()나 First()와 같은 타입을 지정하여 변환하는 확장메서드와 만났을때 실행됩니다.

     

    이러한 지연실행 매커니즘을 통해서 dbcontext의 테이블에 여러가지 조건을 걸고 여러줄에 걸쳐서 작업을 하더라도 

    ToList() 와 같이 변환시켜주는 작업으로 쿼리를 한번만 날리도록 조정이 가능합니다. 

     

    Program.cs에서 UserService를 ServiceProvider를 통해서 User를 생성하고 불러오는 내용을 추가하고 실행하도록 하겠습니다.

     

    using EFSampleProject.context;
    using EFSampleProject.services;
    using Microsoft.Extensions.DependencyInjection;
    
    var collection = new ServiceCollection();
    collection.AddDbContext<BbsContext>();
    collection.AddTransient<UserService>();
    collection.AddTransient<BoardService>();
    var serviceProvider = collection.BuildServiceProvider();
    
    var userService = serviceProvider.GetRequiredService<UserService>();
    
    userService.AddUser("John","John@mail.com");
    userService.AddUser("David","David@mail.com");
    userService.AddUser("Hoon","Hoon@mail.com");
    userService.AddUser("James","James@mail.com");
    
    userService.GetUsersAll().ForEach(x=> Console.WriteLine(x.UserName));

     

    여태까지 과정을 모두 정상적으로 수행하셨다면 저장된 내용이 출력되는 것을 확인 할 수 있습니다.

    John
    David
    Hoon
    James

     

     

     

Designed by Tistory.