diff --git a/Controllers/HomeController.cs b/Controllers/HomeController.cs index f96c3c1..1577914 100644 --- a/Controllers/HomeController.cs +++ b/Controllers/HomeController.cs @@ -1,6 +1,12 @@ -using System.Linq; -using aspnetcoreapp_efcore_inherited_entity_id_problem.Data; +using aspnetcoreapp_efcore_inherited_entity_id_problem.Data; using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.InMemory.Infrastructure.Internal; +using Microsoft.EntityFrameworkCore.InMemory.Storage.Internal; +using Microsoft.EntityFrameworkCore.Metadata.Internal; +using System; +using System.Linq; namespace aspnetcoreapp_efcore_inherited_entity_id_problem.Controllers { @@ -18,28 +24,48 @@ public HomeController(AppDbContext dbContext) public IActionResult Index() { + // Fix for EF Core 3 derived entity types + int maxId = _dbContext.Animal.Max(x => x.Id); + if (maxId == 2) + { + BumpGenerator(_dbContext, typeof(AnimalBase), nameof(AnimalBase.Id), 2); + } + // Uncomment the case you would like to test... // 1st problem: // This causes error "ArgumentException: An item with the same key has already been added. Key: 1". _dbContext.Cat.Add( - new Cat - { - Name = "Tom", - }); + new Cat + { + Name = "Tom", + }); _dbContext.SaveChanges(); // 2nd problem: // This inserts new Dog with id 1 and replaces Cat with id 1. - //_dbContext.Dog.Add( - // new Dog - // { - // Name = "Laika" - // }); - //_dbContext.SaveChanges(); - + _dbContext.Dog.Add( + new Dog + { + Name = "Laika" + }); + _dbContext.SaveChanges(); return View(_dbContext.Animal.ToList()); } + + private static void BumpGenerator( + DbContext context, Type entityClrType, string propertyName, int newLowBound) + { + var entityType = context.Model.FindEntityType(entityClrType); + var property = entityType.FindProperty(propertyName); + var options = context.GetService().FindExtension(); + var inMemoryStore = context.GetService().GetStore(options.StoreName); + var generator = inMemoryStore.GetIntegerValueGenerator(property); + + var values = new object[entityType.GetDeclaredProperties().Count()]; + values[property.GetIndex()] = newLowBound; + generator.Bump(values); + } } } diff --git a/README.md b/README.md index 6c9c42b..e5ec7c1 100644 --- a/README.md +++ b/README.md @@ -1 +1,3 @@ -"# aspnetcoreapp-efcore-inherited-entity-id-problem" +ASP NET Core demo app to demonstarte problem in EF Core 3: +InMemory - bad key management for derived entity types +https://github.com/dotnet/efcore/issues/19854 \ No newline at end of file