Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the point of multiple SaveChanges inside an entity-framework-core transaction?

I'm using EF for my .net-core application and I'm wondering what is the difference between calling SaveChanges multiple times during a transaction and only calling it once before committing. To better illustrate my question, I will provide some pseudo code.

public async Task<IActionResult> AddDepositToHousehold(int householdId, DepositRequestModel model)
{
    using (var transaction = await Context.Database.BeginTransactionAsync(IsolationLevel.Snapshot))
    {
        try
        {
            // Add the deposit to the database
            var deposit = this.Mapper.Map<Deposit>(model);
            await this.Context.Deposits.AddAsync(deposit);

            await this.Context.SaveChangesAsync();

            // Pay some debts with the deposit
            var debtsToPay = await this.Context.Debts
                .Where(d => d.HouseholdId == householdId && !d.IsPaid)
                .OrderBy(d => d.DateMade)
                .ToListAsync();

            debtsToPay.ForEach(d => d.IsPaid = true);

            await this.Context.SaveChangesAsync();

            // Increase the balance of the household
            var household = this.Context.Households
                .FirstOrDefaultAsync(h => h.Id == householdId);

            household.Balance += model.DepositAmount;

            await this.Context.SaveChangesAsync();

            transaction.Commit();
            return this.Ok();
        }
        catch
        {
            transaction.Rollback();
            return this.BadRequest();
        }
    }
} 

As you can see, there are 3 database operations that need to be executed in the transaction. Saving the deposit, updating the debts, and updating the household's balance. Now, I can choose to put SaveChanges after each operation, just like it is shown in the code above, or I can completely discard the first 2 calls to SaveChanges and the behavior of the method will not change in any way. Most of the examples I found on the web contain multiple calls to SaveChanges and I guess there must be some difference between the two approaches. Yet, I cannot find any information what this difference exactly is. Can somebody, please, shed some light on the issue?

like image 434
Hristo Stoichev Avatar asked Apr 07 '19 19:04

Hristo Stoichev


1 Answers

Sometimes it is practical to call SaveChanges, because than you can retrieve the dirty written Id of inserted record. In situations like you mentioned, it may be used to split the database operations to smaller pieces, so when the first small operation wil fail, you will save the rest of the code from execution, meaning less operations to rollback.

like image 109
Tomas Chabada Avatar answered Sep 23 '22 21:09

Tomas Chabada