CLICK HERE TO READ THE ENGLISH VERSION

Update dan Delete Beberapa Record pada Entity Framework Core

Juldhais Hengkyawan
3 min readApr 23, 2024

Terkadang ada kondisi dimana kita harus melakukan update atau delete ke banyak record ketika menggunakan Entity Framework.

Umumnya, kita harus mengambil semua record yang akan di update atau di delete dari database terlebih dahulu sebelum melakukan modifikasi. Hal ini menyebabkan terjadinya multiple roundtrips ke database, yang tentunya berpengaruh terhadap performa aplikasi.

Untungnya pada .NET 8 kita dapat melakukan update dan delete ke banyak record tanpa harus terlebih dahulu mengambil semua record tersebut dari database. Hal ini dapat dilakukan dengan menggunakan extension method ExecuteUpdate dan ExecuteDelete yang telah disediakan oleh Entity Framework Core.

Execute Update

Kita dapat menggunakan method ExecuteUpdate atau ExecuteUpdateAsync untuk langsung meng-update beberapa row pada database untuk setiap entity yang sesuai dengan kriteria query LINQ.

context.Products
.Where(x => x.Category == "Coffee" && x.Price < 10)
.ExecuteUpdate(x => x.SetProperty(p => p.Category, "Cheap Coffee"));

Code di atas akan diterjemahkan ke dalam SQL seperti di bawah ini:

UPDATE Products
SET Category = 'Cheap Coffee'
WHERE Category = 'Coffee' AND Price < 10

Kita dapat meng-update beberapa kolom sekaligus dengan melakukan chaining pada method SetProperty:

context.Products
.Where(x => x.Category == "Coffee" && x.Price < 10)
.ExecuteUpdate(x => x.SetProperty(p => p.Category, "Cheap Coffee")
.SetProperty(p => p.Price, 10));

Code di atas akan diterjemahkan ke dalam SQL berikut:

UPDATE Products
SET Category = 'Cheap Coffee', Price = 10
WHERE Category = 'Coffee' AND Price < 10

Terdapat juga versi asynchronous dari ExecuteUpdate, yaitu ExecuteUpdateAsync:

await context.Products
.Where(x => x.Category == "Coffee" && x.Price < 10)
.ExecuteUpdateAsync(x => x.SetProperty(p => p.Category, "Cheap Coffee"),
cancellationToken);

Execute Delete

Kita dapat menggunakan method ExecuteDelete atau ExecuteDeleteAsync untuk menghapus semua row pada database yang sesuai dengan kriteria pada query LINQ.

context.Product
.Where(x => x.Category == "Coffee" && Price == 0)
.ExecuteDelete();

Code tersebut akan diterjemahkan menjadi SQL seperti berikut:

DELETE FROM Products
WHERE Category = 'Coffee' AND Price = 0

Kita juga bisa menggunakan versi asynchronous-nya:

await context.Product
.Where(x => x.Category == "Coffee" && Price == 0)
.ExecuteDeleteAsync(cancellationToken);

Database Transaction

Method ExecuteUpdate dan ExecuteDelete akan langsung dieksekusi ke database tanpa perlu memanggil method SaveChanges .

Jika terdapat beberapa database command dan kita mau membungkus-nya ke dalam satu transaction, kita perlu membuat database transaction secara manual:

// create new transaction
using var transaction = await context.Database.BeginTransactionAsync(cancellationToken);

try
{
// insert new data using standard approach
var newProduct = Product
{
Name = "Caramel Java Chip",
Category = "Coffee"
Price = 50
};
context.Add(newProduct);
context.SaveChangesAsync(cancellationToken);

// update using ExecuteUpdate
await context.Products
.Where(x => x.Category == "Coffee" && x.Price < 10)
.ExecuteUpdateAsync(x => x.SetProperty(p => p.Category, "Cheap Coffee"),
cancellationToken);

// delete using ExecuteDelete
await context.Product.Where(x => x.Category == "Coffee" && Price == 0)
.ExecuteDeleteAsync(cancellationToken);

// commit transaction
await transaction.CommitAsync(cancellationToken);
}
catch (Exception)
{
// rollback if error
await transaction.RollbackAsync(cancellationToken);
throw;
}

Untuk operasi yang melibatkan data yang besar, penggunaan method ExecuteUpdate atau ExecuteDelete dapat menghasilkan performa yang lebih baik.

Terima kasih telah membaca, semoga bermanfaat 👍

--

--