admin管理员组

文章数量:1410717

Problem: when saving a simple entity to the SQL database, it is occasionally not persisted.

I'm using a .NET application using Microsoft.EntityFrameworkCore.SqlServer v 9.0.2.

The logic is that I check if a record exists in the database table, and if not, then adds it.

My code that adds the record is:

MyEntity e = new()
{
    abc = "abc",
    etc = etc,
};
dbContext.MyEntities.Add(e);

try
{
    await dbContext.SaveChangesAsync(cancellationToken);
}
catch (DbUpdateException e)
{
    if (e.InnerException?.Message.Contains("Violation of Primary Key", StringComparison.OrdinalIgnoreCase) ?? false)
    {
        // Subject of a race-condition, another thread got here first.
    }
    else
    {
        // Try again
        try
        {
            await dbContext.SaveChangesAsync(cancellationToken);
        }
        catch
        {
            logger.LogError(e, "Failed to save changes.");
            throw;
        }
    }
}
catch (Exception e)
{
    // Try again
    try
    {
        await dbContext.SaveChangesAsync(cancellationToken);
    }
    catch
    {
        logger.LogError(e, "Failed to save changes.");
        throw;
    }
}

No exception is thrown.

The vast majority of times this works perfectly but under times (possibly of heavy load?) this is running without throwing an exception, but the entity is not added to the table.

Admittedly, the code is not looking at the return value (which should be 1).

Before making any changes to the code, just wondered if anyone could see any reasons why this wouldn't execute as expected? My expectation is that either that the item was already there, it is added to the database, or it errors.

The DbContext had a lifetime of Scoped, but I've changed that to Transient (zero effect).

My next approach is to look at the INT returned from

await dbContext.SaveChangesAsync(cancellationToken)

and if it's not 1 then throw an exception (unless it was already there).

本文标签: Issue with saving an entity using Entity Framework CoreStack Overflow