EF Core๋ฅผ ์ฌ์ฉํ๋ฉด์ ๊ณต์ ํ ๋งํ ๋ด์ฉ์ ๊ณ์ ๋๊ธ๋ก ๋ฌ๊ฒ ์ต๋๋ค.
record๋ฅผ ์ด์ฉํ ์ผ๋ฐ์ ์ธ ์ํฐํฐ ํํ
public record Slogger(string Id, string Name, string NickName, string Email, bool ConfirmEmail)
{
[Key]
public string Id { get; init; } = Id;
[MaxLength(32)]
public string Name { get; init; } = Name;
[MaxLength(32)]
public string NickName { get; init; } = NickName;
[MaxLength(64)]
public string Email { get; init; } = Email;
public bool ConfirmEmail { get; init; } = ConfirmEmail;
}
์์ค์ฝ๋์์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ง์ด๊ทธ๋ ์ด์ ์ ํ๋ ค๋ฉด
dbContext.Database.Migration()
์ปด๋ผ์ด ์ถ๊ฐ/์ญ์ ๋๊ฑฐ๋, FK๊ฐ ๋ณ๊ฒฝ๋๊ฑฐ๋ ๋ฐ์ดํฐํ์ด ๋ณ๊ฒฝ๋๋ ๋ฑ ์ด๋ด๋ ๋ฐ์ดํฐ๋ ์๋์ผ๋ก ๋ง์ด๊ทธ๋ ์ด์
ํด์ฃผ๋ฉด ์ข๊ฒ ์ง๋ง ๋ฐ์ดํฐ๋ ์๋์ผ๋ก ๋ง์ด๊ทธ๋ ์ด์
ํด์ค์ผ ํ๋ ์ํฉ์ด ์ข
์ข
์๊น๋๋ค. ์ด๊ฒ์ ๋น๋จ ์ฝ๋ ๋ฐฉ์ ๋ฟ๋ง ์๋๋ผ ์ปค๋งจ๋ ๋ฐฉ์๋ ๋ง์ฐฌ๊ฐ์ง์
๋๋ค.
(Add-Migration ํ ๋ฐ์ดํฐ๋ฅผ ์๋์ผ๋ก ๋ง์ด๊ทธ๋ ์ด์
ํ์ง ์์ผ๋ฉด Update-Database ๊ฐ ์คํจํ๋ ๊ฒฝ์ฐ๊ฐ ์ข
์ข
์๊น)
๊ทธ๋์ ์ค์ ํ์
์์๋ ์ Migration()
๋ฅผ ์ธ์ผ์ด ๊ทธ๋ฅ ์๊ฒ ๋ฉ๋๋ค. Microsoft๋ฌธ์์์๋ ์ ๋ฐฉ๋ฒ ๋ณด๋ค๋ SQL ์คํฌ๋ฆฝํธ๋ฅผ ์์ฑํด์ ๋ง์ด๊ทธ๋ ์ด์
ํ๋๊ฒ์ ๊ถ์ฅํฉ๋๋ค.
- ํ๋ก๋์ ํ๊ฒฝ์์์ด ๋ฐฉ๋ฒ์ ์ฌ์ฉ ํ๊ธฐ ์ ์ ์ ์ค ํ ๊ฒ ๊ณ ๋ คํด ์ผ ํฉ๋๋ค. ํ๊ฒฝ์์์ด ๋ฐฐํฌ ์ ๋ต์ ๋จ์์ฑ์ ์์ฑ ๋๋ ๋ฌธ์ ์ ์ํด ์ป๊ฒ ๋ฉ๋๋ค. ๋์ ๋ง์ด๊ทธ๋ ์ด์ ์์ SQL ์คํฌ๋ฆฝํธ๋ฅผ ์์ฑ ํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
์ ๋ณด๋ฅผ ์ ์ฅํ๊ฑฐ๋ ๋ณ๊ฒฝํ ๋ ์ํ์ ๋ฐ๋ฅธ ๋ค์ํ ๋์์ด ํ์ํ๋๋ฐ์,
EF Core๋ ๋ณ๊ฒฝ ์ถ์ ๊ธฐ๋ฅ์ด ์์ด์ SaveChanged
๋ฅผ ํธ์ถํ ๋ ์์ฐ์ค๋ฝ๊ฒ ๋ณ๊ฒฝ๋ด์ฉ์ด ์ ์ฉ๋ฉ๋๋ค.
ํ์ง๋ง ๋๋ถ๋ถ์ ๊ฒฝ์ฐ, API ์๋น์ค๋ฅผ ๊ตฌ์ฑํ๊ฒ ๋๋ฉด์ ์ง์ ์ง์ ๊ณผ ๋ณ๊ฒฝ ์ง์ ์ ๊ณ์ธต์ด ๋ถ๋ฆฌ๋๊ธฐ ๋๋ฌธ์ DbContext๋ก ๊ณ์ ๋ณ๊ฒฝ์ง์ ์ ์ถ์ฒํ ์ ์์ต๋๋ค.
๊ทธ๋์ ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ์์ ๋ ๊ฐ์งํ์ฌ ์ ์ ํ๊ฒ Add ๋๋ Update๋ฅผ ํด์ฃผ๋ฉด ํธ๋ฆฌํ ํ ๋ฐ์,
record์ ๊ฒฐํฉํ์ฌ ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ ์ ์์ต๋๋ค.
public abstract record BaseRecord : ISettableBaseRecord
{
[NotMapped]
public bool IsStored { get; private set; }
[NotMapped]
public bool IsChanged { get; private set; }
public BaseRecord(BaseRecord record)
{
IsStored = record.IsStored;
IsChanged = true;
}
void ISettableBaseRecord.SetSaved()
{
IsStored = true;
IsChanged = false;
}
}
public interface ISettableBaseRecord
{
void SetSaved();
}
public record Slogger(string Id, string Name, string NickName, string Email, bool ConfirmEmail) : BaseRecord
{
[Key]
public string Id { get; init; } = Id;
[MaxLength(32)]
public string Name { get; init; } = Name;
[MaxLength(32)]
public string NickName { get; init; } = NickName;
[MaxLength(64)]
public string Email { get; init; } = Email;
public bool ConfirmEmail { get; init; } = ConfirmEmail;
}
์ดํ BaseRecord๋ฅผ ์ฌ์ฉ๋ฐ์ ์ํฐํฐ๋ค์ ๊ตฌํํ๋ฉด, ์ํฐํฐ ์ธ์คํด์ค๋ง๋ค ์ํ๊ด๋ฆฌ๊ฐ ๊ฐ๋ฅํด์ง๋๋ค.
var slogger = new Slogger("dimohy", "์ ์ธ์ผ", "๋๋ชจ์ด", "dimohy@email.com", false);
// ์์ง DB์ ์ ์ฅํ์ง ์์ ์ํ
Console.WriteLine(slogger);
// ์ ์ฅ ํ
(slogger as ISettableBaseRecord).SetSaved();
// ์ ์ฅ ํ ์ํ
Console.WriteLine(slogger);
// ์์ ๋ฐ์
var slogger2 = slogger with { Name = "์ ์ธํ" };
Console.WriteLine(slogger2);
์ถ๋ ฅ๊ฒฐ๊ณผ
Slogger { IsStored = False, IsChanged = False, Id = dimohy, Name = ์ ์ธ์ผ, NickName = ๋๋ชจ์ด, Email = dimohy@email.com, ConfirmEmail = False }
Slogger { IsStored = True, IsChanged = False, Id = dimohy, Name = ์ ์ธ์ผ, NickName = ๋๋ชจ์ด, Email = dimohy@email.com, ConfirmEmail = False }
Slogger { IsStored = True, IsChanged = True, Id = dimohy, Name = ์ ์ธํ, NickName = ๋๋ชจ์ด, Email = dimohy@email.com, ConfirmEmail = False }
EF Core์ C# 9 record๋ฅผ ์ฌ์ฉํ๋ ค๋ ์ฌ๋์ด ์์ง์ ๋ง์ง๋ ์์ ํ
๋ฐ์
ํ์ฌ๋ ์ธ์์ KeyAttribute๋ฑ์ attribute๋ฅผ ๋ถ์ฌํ ์ ์๊ธฐ ๋๋ฌธ์ record recordName([Key] string Id, ...)
ํํ๋ฅผ ์ธ ์ ๊ฐ ์์ต๋๋ค. ์ธ์์ [Key]๋ฑ์ Attribute๋ฅผ ๋ถ์ฌํ ์ ์๊ฒ EF Core๊ฐ ๋ณํ๊ฐ ํ์ํ ๊ฒ ๊ฐ์ต๋๋ค.
๊ฑฐ๊ธฐ๋ค๊ฐ <Nullable>enable</Nullable>
์ ํ ๊ฒฝ์ฐ ๊ธฐ์กด ๋ฐฉ์์ฒ๋ผ EF Core๋ฅผ ์จ์์ ๊ฒฝ์ฐ ์ํฐํฐ ์์ฑ์ ์๋ง์ ๊ฒฝ๊ณ ๊ฐ ๋จ๋๊ฑธ ๋ณผ ์ ์์ต๋๋ค.
๋์์ธ ํ์์์ DbContext ์์ฑ
Add-Migration
, Update-Database
๋ช
๋ น์ ์ฌ์ฉํ๋ ค๋ฉด, ๋์์ธํ์์ ConnectionString
์ ์ง์ ํด์ DB์ ์ ์ ๊ฐ๋ฅํด์ผ ํฉ๋๋ค.
๋ค์๊ณผ ๊ฐ์ DesignTimeDbContextFactory๋ฅผ ๊ตฌํํ๋ฉด ๋์์ธ ํ์์์ DbContext ์ธ์คํด์ค๋ฅผ ์์ฑํ์ฌ ๋ง์ด๊ทธ๋ ์ด์ ๋ฑ์ ์ฒ๋ฆฌ๋ฅผ ํ ์ ์์ต๋๋ค.
public class SlogContextFactory : IDesignTimeDbContextFactory<SlogContext>
{
public SlogContext CreateDbContext(string[] args)
{
var optionsBuilder = new DbContextOptionsBuilder<SlogContext>();
var config = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();
var connectionString = config["ConnectionStrings:postgresql"];
optionsBuilder.UseNpgsql(connectionString);
return new(optionsBuilder.Options);
}
}