C#C
C#3y ago
Anto

❔ [EF.Core] Discard external relations updates during concurrency conflicts

Hello, I'm in a situation where I have to handle a concurrency conflict inside an asp.net Core application using Npgsql.

I'm using the generic approach suggested by Microsoft (more info here https://learn.microsoft.com/en-us/ef/core/saving/concurrency?tabs=data-annotations#resolving-concurrency-conflicts) and handling a DbUpdateConcurrencyException.

My DB is made of just 2 tables.
A Payments one
public class Payment
{
    public string Id { get; set; }
    public int Amount { get; set; }
    public List<PaymentNotification> Notifications { get; set; }
    public uint Version { get; set; }
}


And a PaymentNotifications one
public class PaymentNotification
{
    public string Id { get; set; }
    public string Name { get; set; }
}


Whenever there's a conflict detected, and the proposed payment entity is carrying new Notifications , I want to keep the the new Amount but discard the latest Notifications:

...
catch (DbUpdateConcurrencyException ex)
{
    foreach (var entry in ex.Entries)
    {
        if (entry.Entity is not Payment) continue;
        
        // take the Amount already stored in the DB
        var proposedValues = entry.CurrentValues;
        var databaseValues = entry.GetDatabaseValues();
        var proposedValue = proposedValues[nameof(Payment.Amount)];
        var databaseValue = databaseValues[nameof(Payment.Amount)];
        proposedValues[nameof(Payment.Amount)] = databaseValue;

        // TODO: discard any eventual proposednotifications
        var proposedNotif = entry.Collection(nameof(Payment.Notifications)).CurrentValue;

        // Refresh original values to bypass next concurrency check
        entry.OriginalValues.SetValues(databaseValues);
        
    }
}
...


I can't find a way to persist the notifications that are already in the database. In the end, I find all the notifications from both the concurrent saves. Can you help me with that?
Was this page helpful?