[ASP.NET Core] .NET Core로 구현한 SPA(Single Page Applications)(6) - EF(Entity Framework)와 코드 퍼스트(Code First)
드디어 EF(Entity Framework)를 연결합니다.
이 프로젝트는 코드 퍼스트(Code First)라 해당 코드가 들어 있지만
다른 방식을 사용한다면 코드 퍼스트 부분은 필요 없습니다.
[ASP.NET Core] 빈 프로젝트 세팅 (1) - 'index.html'을 시작페이지로 설정하기
[ASP.NET Core] 빈 프로젝트 세팅 (2) - WebAPI 설정
[ASP.NET Core] .NET Core로 구현한 SPA(Single Page Applications)(1) - 기초
[ASP.NET Core] .NET Core로 구현한 SPA(Single Page Applications)(2) - Ajax공통 기능, 데이터 바인드 처리
[ASP.NET Core] .NET Core로 구현한 SPA(Single Page Applications)(3) - API 결과 공통 처리
[ASP.NET Core] .NET Core로 구현한 SPA(Single Page Applications)(4) - 인증 기능 추가
[ASP.NET Core] .NET Core로 구현한 SPA(Single Page Applications)(5) - 스웨거(Swagger) 설정
1. EF(Entity Framework) 설치
참고 : [ASP.NET Core 2] EF(Entity Framework) 코어(Core) 코드 퍼스트(Code First)
이 프로젝트는 'SQLite'가 기준입니다.
누겟에서
Microsoft.EntityFrameworkCore.Tools
를 찾아 설치합니다.
사용하려는 DB에 맞는 프로바인더를 설치해야 합니다.
( 참고 : [ASP.NET Core 2] EF(Entity Framework) 코어(Core) 코드 퍼스트(Code First) )
2. DB 연결하기
DB 연결하기위해 커낵션 스트링(Connection String) 만들어 주고 연결하여 DB를 EF와 연동하여 객체화 해야 합니다.
2-1. 커낵션 스트링(Connection String) 만들기
'appsettings.json'파일을 열어 'ConnectionString'를 추가하여 커낵션 스트링을 추가해줍니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | { "Logging": { "LogLevel": { "Default": "Warning" } }, "SpaNetCoreFoundation_mssql": { "DBType": "mssql", "ConnectionString": "Server=[주소];DataBase=[데이터 베이스];UId=[아이디];pwd=[비밀번호]" }, "SpaNetCoreFoundation_sqlite": { "DBType": "sqlite", "ConnectionString": "Data Source=ProjectFile\\SPAFoundation.db" }, "AllowedHosts": "*" } | cs |
'GlobalStatic'에 'DBString'을 추가합니다.
1 2 3 4 5 6 7 8 | /// <summary> /// DB 타입 /// </summary> public static string DBType = ""; /// <summary> /// DB 컨낵션 스트링 저장 /// </summary> public static string DBString = ""; | cs |
'Startup.cs'를 열어 생성자에 위에서 만든 커낵션 스트링을 불러오는 코드를 넣습니다.
1 2 3 4 | //DB 커낵션 스트링 받아오기 string sConnectStringSelect = "SpaNetCoreFoundation_sqlite"; GlobalStatic.DBType = Configuration[sConnectStringSelect + ":DBType"]; GlobalStatic.DBString = Configuration[sConnectStringSelect + ":ConnectionString"]; | cs |
이제 프로젝트가 시작되면 'appsettings.json'파일에서 'ConnectionString'을 받아올 수 있습니다.
2-2. DB 연결 준비하기
코드 퍼스트일 때는 모두 필요하지만 아닐 때는 필요 없는 부분이 있습니다.
2-2-1. DB모델용 폴더 만들기
먼저 'ModelDB'폴더를 만듭니다.
2-2-2. 'User' 클래스 만들기
DB 퍼스트에서는 필요 없습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | /// <summary> /// 유저 사인인 정보. /// 유저기준 정보임. /// </summary> public class User { /// <summary> /// 고유키 /// </summary> [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public long idUser { get; set; } /// <summary> /// 사인인에 사용하는 이메일 /// </summary> public string SignEmail { get; set; } /// <summary> /// 비밀번호 /// </summary> public string Password { get; set; } } | cs |
2-2-3. 컨택스트 만들기
DB 퍼스트라면 이 부분은 자동으로 생성됩니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | public class SpaNetCoreFoundationContext : DbContext { public SpaNetCoreFoundationContext(DbContextOptions options) : base(options) { } public DbSet<User> User { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<User>().HasData(new User { idUser = 1 , SignEmail = "test01@email.net" , Password = "1111" } , new User { idUser = 2 , SignEmail = "test02@email.net" , Password = "1111" }); } } | cs |
2-2-4. 컨택스트 싱글톤 만들기
DB 컨텍스트를 관리하는 방법의 하나가 싱글톤을 만들어 사용하는 것입니다.
그런데 DB 컨텍스트는 싱글톤이 큰 의미가 없습니다.
사용하는데 결국 'using'문을 사용하여 그때그때 자원을 해제하지 않으면 엄청난 메모리 사용량을 자랑하게 됩니다.
'using'문을 사용하면 결국 쓸 때마다 새로 만들어 쓰게 되니 싱글톤이 의미가 없어집니다 ㅎㅎㅎ
이것이 옛날 예제에서는 자주 보이는데 이 프로젝트에서는 싱글톤 없이 그때그때 생성하여 사용하겠습니다.
2-2-5. 기존 유저 모델 제거
기존 모델인 'UserSignInfoModel'을 제거합니다.
나오는 오류를 위에서 만든 'User'모델로 연결하고 데이터는 'GlobalStatic.DBMgr'를 불러다 사용하면 됩니다.
(아직은 없는 게 맞습니다.)
3. DB 연결하기
이것도 기본은 전에 쓴 포스팅과 같습니다.
참고 : [ASP.NET Core 2] EF(Entity Framework) 코어(Core) 코드 퍼스트(Code First)
3-1. DB 연결하기
1 | services.AddDbContext<SpaNetCoreFoundationContext>(); | cs |
3-2. 마이그레이션(Migration)을 만들고 업데이트하기
'마이그레이션(Migration) 정보를 생성하여 버전을 관리하고
이것을 DB에 업데이트하여 프로젝트의 모델 정보를 DB에 업데이트합니다.
아래 명령을 사용하여 마이그레이션을 생성합니다.
1 | Add-Migration DB생성 | cs |
아래 명령을 사용하여 생성된 마이그레이션을 DB에 적용합니다.
1 | update-database DB생성 | cs |
DB에 적용이 잘됐네요.
4. 기존 코드에 EF 사용
기존에 만들어둔 API에 새로 만든 EF를 이용하여 데이터를 검색하고 그 검색된 정보를 리턴하는 코드를 만들어 봅시다
4-1. 기존 코드 제거
기존에는 DB 대신 'GlobalStatic.UserList'를 사용하고 있었습니다.
이제 이 리스트는 필요 없으니 제거해 줍니다.
4-2. 기존 코드 수정
'using' 키워드를 써야 함수가 끝날 때 컨택스트가 가비지 컬렉션을 통하지 않고 정리가 되어 바로 메모리에서 해제가 됩니다.
예>
1 2 3 4 5 6 | using (SpaNetCoreFoundationContext db1 = new SpaNetCoreFoundationContext()) { User mgrItem = db1.User .FirstOrDefault(x => x.idUser == nID); } | cs |
5. 실시간 사인인 리스트 수정
'ModelDB'폴더 밑에 'UserSignIn'를 생성하고 아래와 같이 작성합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | /// <summary> /// 유저 사인인 한 유저의 정보. /// </summary> public class UserSignIn { /// <summary> /// 고유키 /// </summary> [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public long idUserSignIn { get; set; } /// <summary> /// 연결된 유저 사인인 정보 /// </summary> [ForeignKey("idUser")] public User User { get; set; } /// <summary> /// 리플레시 토큰 /// </summary> public string RefreshToken { get; set; } } | cs |
'SpaNetCoreFoundationContext'에 위에서 생성한 모델을 선언해 줍니다.
1 2 | public DbSet<User> User { get; set; } public DbSet<UserSignIn> UserSignIn { get; set; } | cs |
마이그레이션을 생성하고 업데이트합니다.
'SignInItemModel'을 제거하고 오류 나는 부분은 'UserSignIn'으로 바꿔줍니다.
사인인 -> 사인아웃 해보면 DB가 수정되는 것을 확인 할 수 있습니다.
마무리
완성된 샘플 : Github dang-gun - SPA_NetCore_Foundation/SPA_NetCore_Foundation/SPA_NetCore_Foundation06/
DB까지 연결되었으니........
사실상 기능은 완성되었다고 볼 수 있습니다.
이대로 아래 폴더와 파일을 다른 프로젝트에 붙이고
wwwroot
Controllers
Global
IdentityServer4
Model
ModelDB
ProjectFile
User
appsettings.json
Startup.cs
누겟에서 라이브러리만 받아 설치하면 그대로 동작하게 됩니다.