Conversation
|
I also ran into this issue. Specifically, AddDbContextPool() sets the ImplementationFactory property, so the ImplementationType property is null. I tested the fix from @iwedaz with .NET 8 with a local build based on the last commit before the .NET 10 update (here) and it fixed the issue for me. @edandersen Would you consider merging this update? The ASP.NET Get Started With EF Core page does not mention DbContext pooling, but it is the first thing mentioned on the Advanced Performance Topics page, so I'm sure others will run into this. |
|
It looks like #119 is trying to address the same issue, although it has slightly different code to fix it. |
| foreach (var service in services.ToList()) | ||
|
|
||
| var dbContextImplementations = services | ||
| .Where(x => x.Lifetime is ServiceLifetime.Scoped && x.ServiceType.IsSubclassOf(typeof(DbContext))) |
There was a problem hiding this comment.
Is the addition of the ServiceLifetime.Scoped check here an important change? It's unclear how that check is related to the core purpose of this PR (supporting AddDbContextPool()).
| foreach (var dbContextImplementation in dbContextImplementations) | ||
| { | ||
| if (service.ImplementationType == null) | ||
| continue; | ||
| if (service.ImplementationType.IsSubclassOf(typeof(DbContext)) && | ||
| !discoveredServices.Any(x => x.DbContextType == service.ImplementationType)) | ||
| foreach (var dbSetProperty in dbContextImplementation.ServiceType.GetProperties()) | ||
| { | ||
| foreach (var dbSetProperty in service.ImplementationType.GetProperties()) | ||
| // looking for DbSet<Entity> | ||
| if (dbSetProperty.PropertyType.IsGenericType && dbSetProperty.PropertyType.Name.StartsWith("DbSet")) | ||
| { | ||
| // looking for DbSet<Entity> | ||
| if (dbSetProperty.PropertyType.IsGenericType && dbSetProperty.PropertyType.Name.StartsWith("DbSet")) | ||
| if (!options.IgnoreEntityTypes.Contains(dbSetProperty.PropertyType.GenericTypeArguments.First())) | ||
| { | ||
| if (!options.IgnoreEntityTypes.Contains(dbSetProperty.PropertyType.GenericTypeArguments.First())) | ||
| { | ||
| discoveredServices.Add(new DiscoveredDbSetEntityType() { | ||
| DbContextType = service.ImplementationType, | ||
| DbSetType = dbSetProperty.PropertyType, | ||
| UnderlyingType = dbSetProperty.PropertyType.GenericTypeArguments.First(), Name = dbSetProperty.Name }); | ||
| } | ||
| discoveredServices.Add(new DiscoveredDbSetEntityType { |
Current implementation don't find user implemented DbContext that injected with AddDbContextPool().
If you compare different versions of AddDbContext() and AddDbContextPool() extension methods, you will see all of them have the same registration for scoped user DbContext implementation.
EF Core 6
AddDbContextPool
AddDbContext
EF Core 7
AddDbContextPool
AddDbContext
EF Core 8
AddDbContextPool
AddDbContext
Therefor this approach for searching user implemented DbContext registrations is more universal.