Skip to content

Commit

Permalink
Applied fix according to dotnet/efcore#19854 (comment)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ondřej Kaláb committed Jun 11, 2020
1 parent 3a737c7 commit 0545d3f
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 14 deletions.
52 changes: 39 additions & 13 deletions Controllers/HomeController.cs
Original file line number Diff line number Diff line change
@@ -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
{
Expand All @@ -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<IDbContextOptions>().FindExtension<InMemoryOptionsExtension>();
var inMemoryStore = context.GetService<IInMemoryStoreCache>().GetStore(options.StoreName);
var generator = inMemoryStore.GetIntegerValueGenerator<int>(property);

var values = new object[entityType.GetDeclaredProperties().Count()];
values[property.GetIndex()] = newLowBound;
generator.Bump(values);
}
}
}
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 0545d3f

Please sign in to comment.