[EFCore] 초기값 설정하기
·
공부/EFCore
초기값 설정에 크게 2가지 차이점이 있다. Entity class 자체의 초기값과 DB Table 차원의 초기값이다. 1️⃣ Auto-Property Initializer public DateTime CreateDate { get; set; } = new DateTime(2020, 1, 1); 이는 Entity 차원의 초기값으로 SaveChanges로 DB에 적용하지 않는 이상 DB에는 적용되지 않는다. 2️⃣ Fluent API builder.Entity() .Property("CreateDate") .HasDefaultValue(DateTime.Now); DB Table DEFAULT를 적용하는 방식이다. DB에 적용된다. 3️⃣ SQL Froagment builder.Entity() .Propert..
[EFCore] 다수의 Entity Class를 하나의 테이블에 매핑하기
·
공부/EFCore
Item과 ItemDetail을 하나로 합치고 싶다. builder.Entity().ToTable("Items"); builder.Entity().ToTable("Items"); AppDbContext에 내용을 추가해준다. 짠.
[EFCore] 상속 관계를 매핑해보자 : Table Per Hierarchy (THP) 만들기
·
공부/EFCore
게임 내에 여러 아이템 중 이벤트 기간 동안만 생성됐다가 기간이 끝나면 삭제되는 아이템이 있다. 그런 이벤트아이템은 기존 아이템의 모든 속성을 상속받고 자신의 특징으로는 사라지는 기한만을 설정한다. 이 두 아이템을 다른 테이블로 설정하기 보다는 같은 아이템 테이블에 넣고, 상속 여부만 체크해주는 편이 좋다. 이런 상황에서 THP를 사용하면 된다. ✅ Convention으로 만들기 public class EventItem : Item { public DateTime DestroyDate { get; set; } } 기존 아이템을 만드는 클래스에서 Item을 상속 받는 EventItem 클래스를 만들어준다. new EventItem() { TemplateId = 102, CreateDate = DateTim..
[EFCore] Entity와 DB, Table 연동하기
·
공부/EFCore
public class ItemOption { public int Str { get; set; } public int Dex { get; set; } public int Hp { get; set; } } public class Item { public ItemOption Option { get; set; } // ... // } items[0].Option = new ItemOption() { Dex = 1, Hp = 2, Str = 3 }; 예시 상황이다. AppDbContext에 둘 중 하나를 추가해주면 된다. 1️⃣ OwnsOne builder.Entity() .OwnsOne(i => i.Option); 이를 추가해서 새로운 테이블을 만들면, Option_Str, Option_Dex, Option_..
[EFCore] Shadow Property와 Backing Field
·
공부/EFCore
✅ Shadow Property class에는 있지만 DB에는 데이터가 없는 경우, [NotMapped] 혹은 .Ignore()로 해결한다. 반대로 DB에는 데이터가 있지만 class에는 없는 경우를 Shadow Property라고 한다. Shadow Property를 생성할 때는 .Property("프로퍼티이름") 으로 한다. 접근할때는 .Property("프로퍼티이름").CurrentValue로 한다. 망가진 아이템을 고친 날짜를 Shadow Property로 만들고 싶다고 하면, 우선 Data 생성란에 RecoveredDate를 추가해준다. db.Entry(items[0]).Property("RecoveredDate").CurrentValue = DateTime.Now; AppDbContext에도 ..
[EFCore] 다수의 Navigational Property가 같은 클래스를 참조하는 상황, 어떻게 대처할까
·
공부/EFCore
public class Item { // ... // public Player Owner { get; set; } public Player Creator { get; set; } } 아이템을 생성한 Player와 아이템을 소유하고 있는 Player를 모두 나타내고 싶을 때는 어떤 방법을 사용해야 할까? 기존에 사용하던 Convention 방식을 사용하면 에러가 발생한다. (OwnerId와 CreatorId 두 개를 추가해주는 방식) ✅ 이때 우리가 사용할 수 있는 게 DataAnnotation 방식이다. public class Item { // ... // public int? OwnerId { get; set; } [InverseProperty("OwnedItem")] public Player Owne..
[EFCore] Convention을 알아보자
·
공부/EFCore
✅ Convention 1️⃣ Entity Class 관련 내용 - Public + Non-static 이어야 한다. - property 중에서 public getter를 찾으며 분석한다. -property 이름 = table column 이름으로 생선된다. 2️⃣ 이름, 크기, 형식 - .NET 형식 🔁 SQL 형식(int, bool)이 자동으로 변환된다. - .NET 형식의 기본 Nullable 여부를 따라간다. 3️⃣ PRIMARY 관련 - Id 혹은 Id 로 정의된 property가 Primary Key로 설정된다. (후자를 추천한다. C# 코딩할 때 이름 구분이 가야 편리하다.) - 복합키(Composite Key)는 Convention으로 처리 불가하다.
[EFCore] 데이터를 임시로 삭제해보자 : Soft Delete (HasQueryFilter/IgnoreQueryFilter)
·
공부/EFCore
게임에서 아이템을 실수로 삭제하면 복구해주는 경우가 있다. 만약 우리가 아이템을 '삭제'한 게 정말 'Delete'를 의미했다면 복구가 불가능했을 것이다. 이럴 때 사용할 수 있는 게 바로 HasQueryFilter다. public class Item { public bool SoftDeleted { get; set; } //...// } Item 클래스에 SoftDeleted를 추가해준다. true가 임시 삭제를 의미하고, false가 기본값이다. protected override void OnModelCreating(ModelBuilder builder) { // 앞으로 Item Entity에 접근할 때 항상 사용되는 모델 레벨의 필터링 // 필터를 무시하고 싶으면 IgnoreQueryFilter사용..
[EFCore] Relationship Data 수정 하기
·
공부/EFCore
1️⃣ 1 대 1 관계에서 데이터 수정 Player는 하나의 Item만 소지할 수 있다. Player의 아이템 명을 변경해보자. public static void Update_1v1() { ShowItems(); Console.WriteLine("Input ItemSwitch PlayerId"); Console.Write(" > "); int id = int.Parse(Console.ReadLine()); using (AppDbContext db = new AppDbContext()) { Player player = db.players .Include(p => p.Item) // Include가 빠지면 Item이 Player를 참조하고 있다는 사실을 알 수 없어 Error 발생 .Single(p => p..
[EFCore] Pricipal 데이터가 없을 때 Dpendent 데이터가 존재할 수 있는가?
·
공부/EFCore
Pricipal 데이터가 없을 때 Dpendent 데이터가 존재할 수 있는가? ✅ Nullable 유무에 따라 다르다. 1️⃣ OwnerId가 Nullable로 설정되지 않았을 때 OwnerId 하나를 삭제하면, public class Item { public int ItemId { get; set; } public int TemplateId { get; set; } public DateTime CreateDate { get; set; } public int OwnerId { get; set; } public Player Owner { get; set; } } Test를 통해 PlayerId가 1인 Owner 정보를 삭제하자 Owner 뿐만 아니라 Item 정보도 모두 사라졌다. 2️⃣ OwnerId가 ..
[EFCore] Disconnected Update (Reload / Full Update)
·
공부/EFCore
Disconnected Update는 Update 단계가 이어서 일어나지 않고, 끊겨서 일어나는 경우다. 예를 들어 홈페이지에서 개인정보를 수정한다고 했을 때 홈페이지는 DB에서 닉네임, 이메일 등의 정보를 끌어와 우리에게 보여준다. 우리는 기존 정보를 확인한 뒤 나중에 정보를 수정하는 과정을 겪는다. 이게 바로 Disconnected Update다. Dinsconnected Update에도 2가지 다른 방식이 있다. Reload와 Full Update다. 1️⃣ Reload 필요한 정보만 보내서 수정한다. public static void UpdateByReload() { // 외부에서 수정을 원하는 데이터의 ID / 정보 넘겨줬다고 가정 Console.WriteLine("Input GuildId");..
[EFCore] DTO 활용하기
·
공부/EFCore
DTO란 Data Transfer Object의 준말이다. 우리가 DB에서 원하는 정보를 빼오기 위해 Select 구문을 이용하는 기존 함수를 살펴보자. using (var db = new AppDbContext()) { var info = db.Guilds .Where(g => g.GuildName == name) .Select(g => new { Name = g.GuildName, MemberCount = g.Members.Count }) .First(); Console.WriteLine($"GuildName ({info.Name}), MemberCount({info.MemberCount})"); } Select 뒷 부분을 유심히 살펴보면 Guild의 정보를 뽑아오기 위해 Guild를 새롭게 가공하는..
[EFCore] DB에 존재하는 데이터 수정하기
·
공부/EFCore
1️⃣ Tracked Entity를 얻어온다. 2️⃣ Entity 클래스의 property를 변경한다. (Set) 3️⃣ SaveChanges를 호출한다. public static void UpdateTest() { using (AppDbContext db = new AppDbContext()) { var guild = db.Guilds.Single(g => g.GuildName == "T1"); // 1번 guild.GuildName = "DWG"; // 2번 db.SaveChanges(); // 3번 } } 변경사항을 적용할 때 변경사항만 업데이트되는 것인지, 변경되지 않은 부분까지 업데이트 되는 것인지 궁금할 수 있다. SaveChanges를 호출하게 되면 내부에서 DetectChanges 함수를 ..
[EFCore] DB에 이미 존재하는 사용자를 PK로 연결하려면?
·
공부/EFCore
1️⃣ Tracked Instance를 얻어온다. 2️⃣ 데이터를 연결한다. 매우 단순하다... public class DbCommands { public static void InitializeDB(bool forceReset = false) { using (AppDbContext db = new AppDbContext()) { if (!forceReset && (db.GetService() as RelationalDatabaseCreator).Exists()) return; db.Database.EnsureDeleted(); db.Database.EnsureCreated(); CreateTestData(db); Console.WriteLine("DB Initialized"); } } public st..
[EFCore] SaveChanges를 호출하면 어떤 일이 일어날까
·
공부/EFCore
1️⃣ 추가된 객체들의 상태가 Unchaged로 바뀐다. 참고 : https://codingjin0424.tistory.com/124 2️⃣ SQL Identity로 PK를 관리한다. ▶ DB에 데이터를 추가한 후 ID를 클라로 받아와 객체의 ID Property를 채워준다. 3️⃣ Relationship을 참고해서 FK 세팅 및 연결을 완료한다. public class DbCommands { public static void InitializeDB(bool forceReset = false) { using (AppDbContext db = new AppDbContext()) { if (!forceReset && (db.GetService() as RelationalDatabaseCreator).Exis..