EF core tries to update Alternate Key SQL identity column.
- Dominant language
- C#
- Stars
- 14.8k
- Forks
- 3.4k
- PR merge metrics
- PR metrics pending
Description
Given the following entity
```
public class MyEntity {
public virtual Guid PersistenceId { get; private set; }
public virtual int MyEntityId { get; private set; }
public virtual string Name { get; set; }
}
```
Using fluent API for EF configuration
```
public class MyEntityConfig : IEntityTypeConfiguration {
public void Configure(EntityTypeBuilder builder) {
builder.ToTable("MyEntities");
builder.HasKey(x => x.PersistenceId);
builder.Property(x => x.PersistenceId).ValueGeneratedOnAdd().HasDefaultValueSql("newid()");
builder.HasAlternateKey(x => x.MyEntityId);
builder.Property(x => x.MyEntityId).ValueGeneratedOnAdd();
builder.Property(x => x.Name).HasMaxLength(100);
}
}
```
Everything works as intended when the entity is first added to the database. When the entity is updated and changes are saved back to the database, SQL Server throws an exception "cannot update identity column 'MyEntityId'.
```
Message:
Microsoft.EntityFrameworkCore.DbUpdateException : An error occurred while saving the entity changes. See the inner exception for details.
---- Microsoft.Data.SqlClient.SqlException : Cannot update identity column 'MyEntityId'.
Stack Trace:
ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
SqlServerModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken)
BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken)
BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken)
StateManager.SaveChangesAsync(IList`1 entriesToSave, CancellationToken cancellationToken)
StateManager.SaveChangesAsync(StateManager stateManager, Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
<5 more frames...>
<>c.b__209_0(Task`1 result)
ContinuationResultTaskFromResultTask`2.InnerInvoke()
ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
--- End of stack trace from previous location ---
RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
```
It appears like EF Core is sending the MyEntityId column in the update statement even though it's marked as an AlternateKey with ValueGeneratedOnAdd.
EF Core version: 8.0.1
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: .NET 8.0
Operating system: Windows 10 22H2
IDE: Visual Studio 2022 17.8.2
Contributor guide
Assessment
This issue has not been assessed yet.