๋ฌธ์์ด ๊ธฐ๋ฐ orm ์ ํ๊ณ๋ ์ฌ์ค ์๋์ ๊ฐ์ ๋ณต์กํ ์๊ตฌ์ฌํญ์ ๋์ํ ๋ ๋๋ฌด ๋ง์ ๋
ธ๋์ ๊ฐ์ํ๋ค๋ ์ ์ ์์ต๋๋ค.
// Dapper
public async Task<long> CreateCompleteOrderAsync(Order order, IEnumerable<OrderItem> items, Payment payment, Shipment shipment)
{
await using var conn = new NpgsqlConnection(_connectionString);
await conn.OpenAsync();
await using var transaction = await conn.BeginTransactionAsync();
try
{
var orderId = await InsertAsync(order);
await transaction.CommitAsync();
return orderId;
}
catch
{
await transaction.RollbackAsync();
throw;
}
}
// Nuvatis
public async Task<long> CreateCompleteOrderAsync(Order order, IEnumerable<OrderItem> items, Payment payment, Shipment shipment)
{
// ํธ๋์ญ์
์ฒ๋ฆฌ ํ์ - ๊ฐ์ํ
var orderId = await _mapper.InsertAsync(order);
return orderId;
}
๊ทธ๋ฐ ์ ๋๋ฌธ์ ๋ฒค์น๋งํฌ์์๋ ๊ตฌํํ์ง ๋ชปํ๊ณ Insert ๋ก ๋์ ํ ๋ฏ ๋ณด์
๋๋ค.
์ฌ์ค, ์ ์ฝ๋๋ ํ
์คํธ ์คํจ๋ผ์, ๋ฒค์น๋งํฌ์ ๊ฒฐ๊ณผ๊ฐ ์๋ฌด๋ฐ ์๋ฏธ๊ฐ ์์ต๋๋ค.
ํ
์คํธ๋ฅผ ํจ์คํ๋ ค๋ฉด, ๋ก์ง๊ณผ ์ฟผ๋ฆฌ๊ฐ ๋งค์ฐ ๋ณต์กํ๊ฒ ์ฝํ๋ ์ํฉ์ ํผํ ์๋ ์์ ๊ฒ์
๋๋ค.
// Dapper
public async Task<long> CreateCompleteOrderAsync(Order order, IEnumerable<OrderItem> items, Payment payment, Shipment shipment)
{
if (order.Id != default || order.OrderItems.Count != 0 || order.Shipment != null || order.Payment != null)
throw new InvalidArguementException("์ ๊ท๋ก ์์ฑ๋ ๊ฐ์ฒด๊ฐ ์๋.");
await using var conn = new NpgsqlConnection(_connectionString);
await conn.OpenAsync();
await using var transaction = await conn.BeginTransactionAsync();
try
{
// order ์ ์ฅ ํ ์ธ๋ํค ํ๋,
foreach(var item in items)
{
if (item.Id == default)
{
// Insert
}
else
{
// Update
}
}
// shipment, payment ๋์ผ ๊ณผ์ ๋ฐ๋ณต
์ด๋ฐ ์ํฉ์ด ์ด ๋ฉ์๋๊ฐ ์ ์ผํ์ง๋ ์์ ๊ฒ์
๋๋ค.
์ฌ๋ฐ๋ ์ ์ EF Core ์ ๊ตฌํ๋ ์คํจ ์ฝ๋๋ฅผ ๊ธฐ๊ณ์ ์ผ๋ก ๋ต์ตํ๊ณ ์์ต๋๋ค.
// EF Core
public async Task<long> CreateCompleteOrderAsync(Order order, IEnumerable<OrderItem> items, Payment payment, Shipment shipment)
{
await using var transaction = await _context.Database.BeginTransactionAsync();
try
{
_context.Orders.Add(order);
await _context.SaveChangesAsync();
await transaction.CommitAsync();
return order.Id;
}
catch
{
await transaction.RollbackAsync();
throw;
}
}
์ฌ์ค, EF Core ๋ ChangeTracker ๊ฐ ๋ณต์กํ ๋ก์ง - Insert ํ ๊ฒ๊ณผ Update ํ ๊ฒ์ ๊ตฌ๋ถํ๋ ๊ฒ์ ๋ค ํด๊ฒฐํด์ฃผ๊ธฐ ๋๋ฌธ์, ์๋์ ๊ฐ์ด ๊ฐ๋จํ๊ฒ ๊ตฌํํด๋ ๋ฉ๋๋ค.
// EF Core
public async Task<long> CreateCompleteOrderAsync(Order order)
{
_context.Orders.Add(order);
var affected = await _context.SaveChangesAsync();
return affected > 0 ? order.Id : -1;
}
SaveChanges(Async) ๋ ์๋ฌต์ ์ผ๋ก Transcation ์ ์ฐ๊ธฐ ๋๋ฌธ์ ๊ตณ์ด Transaction ์ ์ถ๊ฐํ ํ์๋ ์์ต๋๋ค.
ChangeTracker ์ ๊ธฐ๋ฐํ ์ ์ฝ๋๋ ์ฌ์ค ํ
์คํธ๊ฐ ํ์์์ ์ ๋๋ก ์ ํํ๊ฒ ๋์ํฉ๋๋ค.
์ฑ๋ฅ ๋น์ฉ์ ์ง๋ถํ๋ฉด์๊น์ง EF Core๋ฅผ ์ฌ์ฉํ๋ ์ด์ ๋ ์ด๋ฐ ์ ํ์ฑ๊ณผ ์ฝ๋ฉ ํจ์จ๋๋ฌธ์
๋๋ค. (Linq ์ ํจ์จ๋ ์ด๋ง์ด๋งํ๊ณ DB ๊ด๋ฆฌ๋๊ตฌ๋ ์์ฒญ๋์ฃ )
NuVatis ๊ฐ ์์ ๊ฐ์ ๋ณต์กํ ์๊ตฌ ์ฌํญ์๋ ๋์ํ๊ธฐ ์ํด์๋ ChangeTracker ์ ์ ์ฌํ ๊ธฐ๋ฅ์ ๊ตฌํํด์ผ ํ๋๋ฐ, ๊ทธ๋ฌ๋ฉด ์ ์ ๋นํจ์จ์ด๋ผ๊ณ ๋นํํ๋ EF Core ์ ๋ ๋ค๋ฅธ ๋ฒ์ ์ด ๋๊ณ , ๋ง์ฝ ๋์ํ์ง ๋ชปํ๋ค๋ฉด ์๊ฐ๋ฝ ํ์ ๊ฐ์ํ๋ ๊ทธ์ ๊ทธ๋ฐ ๋๊ตฌ๋ก ์ ๋ฝํ๋ ์์ด๋ฌ๋๊ฐ ๋ฐ์ํฉ๋๋ค.
์ด๋ฐ ์์ด๋ฌ๋๋ ์กด์ค ๋ณด๋ค๋ ์ฃ๋ถ๋ฅธ ๋นํ์ด ๋จผ์ ์๋ ๊ฒ์ด ์์ธ์ด์ง ์์๊นํ๋ ์๊ฐ์ด ๋ญ๋๋ค.