Following code throws exception:
System.InvalidOperationException: The instance of entity type 'DimEntity' cannot be tracked because another instance with the same key value for {'EntityEntityId'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached
var optionsBuilder = new DbContextOptionsBuilder<MyDbContext>();
optionsBuilder.UseInMemoryDatabase("Test");
using (var dbContext = new MyDbContext(optionsBuilder.Options))
{
//when I comment this line, the rest works file
dbContext.DimEntity.Add(new DimEntity { EntityEntityId = 0, EntityKey = "Uknown" });
//otherwise this line throws the exception
dbContext.DimEntity.Add(new DimEntity { EntityEntityId = 1, EntityKey = "DFS Region" });
= "Europe Region" });
dbContext.DimEntity.Add(new DimEntity { EntityEntityId = 2, EntityKey = "Europe Region" });
}
Why?
Additional Details:
public partial class MyDbContext : DbContext
{
public MyDbContext (DbContextOptions<MyDbContext> options)
: base(options)
{
}
public virtual DbSet<DimEntity> DimEntity { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<DimEntity>(entity =>
{
entity.HasKey(e => e.EntityEntityId);
entity.ToTable("DimEntity", "mm");
entity.Property(e => e.EntityEntityId).HasColumnName("Entity_EntityID");
});
}
}
public partial class DimEntity
{
public int EntityEntityId { get; set; }
public string EntityKey { get; set; }
}
It's not in memory provider specific. By convention int
PKs are considered auto increment (SqlServer identity
), so the problem is similar to when adding explicit values to auto increment column.
If you keep your new DimEntity { EntityEntityId = 0, ... }
in a variable, you'll see that after Add
the value of the EntityEntityId
will be 1 (because when the PK value is default (0 for int
), the value generation on add is performed).
But when you add entity with non default int
PK, no value generation occurs and the exception is thrown for EntityEntityId = 1
because it already exist - the generated value for the first entity you've added first.
In general, if you don't want PK value generation, you should opt-in for that inside OnModelCreating
:
entity.Property(e => e.EntityEntityId)
.HasColumnName("Entity_EntityID")
.ValueGeneratedNever(); // <--