Skip to content

DbUpdateException Entries Behaves Differently When First Fails vs Others Fail #1449

@philvmx1

Description

@philvmx1

Using EF Core 6.0.8 with Pomelo 6.0.0, when we have the following:

Table - Person
| Id | Name (max 3) |

context.Add<Person>(new Person { Name = "Three" });
context.Add<Person>(new Person { Name = "A" });
context.Add<Person>(new Person { Name = "B" });
context.Add<Person>(new Person { Name = "C" });

try
{
  context.SaveChanges();
}
catch (DbUpdateException ex)
{
  ex.Entries.Count(); // 4
}

However, when we have it where the first record does not have an error:

context.Add<Person>(new Person { Name = "Three" });
context.Add<Person>(new Person { Name = "A" });
context.Add<Person>(new Person { Name = "Three" });
context.Add<Person>(new Person { Name = "B" });
context.Add<Person>(new Person { Name = "C" });

try
{
  context.SaveChanges();
}
catch (DbUpdateException ex)
{
  ex.Entries.Count(); // 1
}

Only the one record is in Entries.

We expect this to be consistent and only have the 1 Entry that failed.

The cause of this happening is the InitAsync, which is attempting to read the first result - fails and throws an exception.

await m_resultSet.ReadResultSetHeaderAsync(ioBehavior).ConfigureAwait(false);

That exception is caught and EF Core selects all Entries whereas in ConsumeAsync, it only selects the current command Entry.

https://github.com/dotnet/efcore/blob/42e6cfbd0c5b431a89b1923e7b73296705cf7ddf/src/EFCore.Relational/Update/ReaderModificationCommandBatch.cs#L383

ExecuteReaderAsync should return a reader, but perhaps shouldn't read anything. Not sure what other implementations are doing though.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions