Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using pooling for multiple DbContexts causes exception #9433

Closed
maximtarasov opened this issue Aug 16, 2017 · 20 comments
Closed

Using pooling for multiple DbContexts causes exception #9433

maximtarasov opened this issue Aug 16, 2017 · 20 comments
Assignees
Labels
closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. type-bug
Milestone

Comments

@maximtarasov
Copy link

maximtarasov commented Aug 16, 2017

Exception message:
System.ArgumentException: Expression of type 'Microsoft.EntityFrameworkCore.DbContextOptions`1[MultiContext.Contexts.BContext]' cannot be used for constructor parameter of type 'Microsoft.EntityFrameworkCore.DbContextOptions`1[MultiContext.Contexts.AContext]' Parameter name: arguments[0]
Stack trace:
at System.Dynamic.Utils.ExpressionUtils.ValidateOneArgument(MethodBase method, ExpressionType nodeKind, Expression arguments, ParameterInfo pi, String methodParamName, String argumentParamName, Int32 index) at System.Dynamic.Utils.ExpressionUtils.ValidateArgumentTypes(MethodBase method, ExpressionType nodeKind, ReadOnlyCollection`1& arguments, String methodParamName) at System.Linq.Expressions.Expression.New(ConstructorInfo constructor, IEnumerable`1 arguments) at System.Linq.Expressions.Expression.New(ConstructorInfo constructor, Expression[] arguments) at Microsoft.EntityFrameworkCore.Internal.DbContextPool`1.CreateActivator(DbContextOptions options) at Microsoft.EntityFrameworkCore.Internal.DbContextPool`1..ctor(DbContextOptions options) --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProvider provider) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProvider provider) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitSingleton(SingletonCallSite singletonCallSite, ServiceProvider provider) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceProvider.<>c__DisplayClass22_0.b__0(ServiceProvider provider) at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetService[T](IServiceProvider provider) at Microsoft.Extensions.DependencyInjection.EntityFrameworkServiceCollectionExtensions.<>c__2`1.b__2_1(IServiceProvider p) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, ServiceProvider provider) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProvider provider) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceProvider.<>c__DisplayClass22_0.b__0(ServiceProvider provider) at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType) at Microsoft.Extensions.Internal.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, Boolean isDefaultParameterRequired) at lambda_method(Closure , IServiceProvider , Object[] ) at Microsoft.AspNetCore.Mvc.Controllers.ControllerActivatorProvider.<>c__DisplayClass4_0.b__0(ControllerContext controllerContext) at Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider.<>c__DisplayClass5_0.g__CreateController0(ControllerContext controllerContext) at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.d__14.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.d__22.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context) at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.d__17.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.d__15.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNetCore.Builder.RouterMiddleware.d__4.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.d__7.MoveNext()
public class BContext : DbContext
{
    public BContext(DbContextOptions<BContext> options) : base(options) { }
}

public class AContext : DbContext
{
    public AContext(DbContextOptions<AContext> options) : base(options) { }
}
services.AddDbContextPool<AContext>(options =>
{
    options.UseInMemoryDatabase("AContext.InMemory");
});
services.AddDbContextPool<BContext>(options =>
{
    options.UseInMemoryDatabase("BContext.InMemory");
});

Further technical details

EF Core version: 2.0.0
Database Provider: Microsoft.EntityFrameworkCore.InMemory 2.0.0
Operating system: Mac OS X High Sierra
IDE: Rider

@maximtarasov maximtarasov changed the title Using pooling for multiple DbContexts causes error Using pooling for multiple DbContexts causes exception Aug 16, 2017
@ColinRaaijmakers
Copy link

Got the same problem, using multiple DbContexts with .UseSqlServer.

@ajcvickers
Copy link
Member

Note for people hitting this: the workaround is to not use pooling. (Pooling can give some perf improvements, but if it is so much that it is needed by your app to even function then I'd be very interested to see the numbers. We will, of course, fix this, but probably not until the 2.1 release.)

@ajcvickers ajcvickers added this to the 2.1.0 milestone Aug 18, 2017
@ajcvickers
Copy link
Member

@anpete There is a PR for this, but it looks like it needs some work.

@leonidmln
Copy link

i had the same problem, you need to change code #9465

anpete added a commit that referenced this issue Aug 19, 2017
- Adds missing DbContextOptions generic parameter.
anpete added a commit that referenced this issue Aug 21, 2017
- Adds missing DbContextOptions generic parameter.
@anpete anpete closed this as completed in a661feb Aug 21, 2017
@paultechguy
Copy link

Yepper, same issue here. All same symptoms...using more than one DbContext with AddDbContextPool causes exception.

@anpete
Copy link
Contributor

anpete commented Aug 23, 2017

Note for people hitting this: you should be able to workaround the issue by overriding the default DI configuration for DbContextPool to match this.

@leonidmln
Copy link

They created wrong tests.
This fix ec894e9 is ok, not new one

@ajcvickers
Copy link
Member

@leonidmln Can you explain in some detail what is wrong with the fix? We're planning to ship this soon, so if it doesn't work, then it would be really great to find out before we ship it, but we can't see what is wrong. Can you post some code that shows what is not working?

@Megasware128
Copy link

Megasware128 commented Aug 30, 2017

@ajcvickers While it does work, I believe the current fix is more like fixing the problem but not the "source" of the problem. You shouldn't even be able to throw a different kind of DbContextOptions in the constructor of DbContextPool<TContext>. It should be constraint to DbContextOptions<TContext>

@Megasware128
Copy link

@anpete @ajcvickers Also what @leonidmln said. The tests are not correct. SecondContext should have DbContextOptions<SecondContext> as parameter in the constructor because that is where the problem lies. Most people use DbContextOptions<T> in the constructor of their Context's if they have multiple Context's because that is how DI knows which Options object should be given to which Context. Otherwise wrong ConnectionStrings might be used.

@ajcvickers
Copy link
Member

Hi @maximtarasov, @ColinRaaijmakers, @leonidmln, @paultechguy, @Megasware128. We are gathering information on the use of EF Core pre-release builds. You reported this issue shortly after the release of 2.0.0 RTM. It would be really helpful if you could let us know:

  • Did you consider testing your code against the pre-release builds?
  • Was there anything blocking you from using pre-release builds?
  • What do you think could make it easier for you to use pre-release builds in the future?

Thanks in advance for any feedback. Hopefully this will help us to increase the value of pre-release builds going forward.

@ColinRaaijmakers
Copy link

ColinRaaijmakers commented Sep 28, 2017

@ajcvickers Sorry for my late response.

I consciously waited for the release 2.0 before testing if AddDbContextPool worked correctly because I knew it would be in 2.0 release. Assuming that this 'just' would work.

Due to many different production sites, I prefer to test stable release rather than pre-builds.

@ajcvickers ajcvickers added the closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. label Oct 6, 2017
@brendanalexdr
Copy link

I'm getting this error too. But is not clear to me know I can take advantage of this fix. I clumsily tried to download the repo and referenced the latest Microsoft.EntityframeworkCore in my project, but ended up mired in errors. What's the recommended way to implement this fix?

@ajcvickers
Copy link
Member

@nukuuk The fix has now been shipped yet. The easiest workaround is to use AddDbContext instead of AddDbContextPool.

@ColinRaaijmakers
Copy link

What is the easiest way to test this fix for me?

@ghost
Copy link

ghost commented Oct 21, 2017

Same here

@oncicaradupopovici
Copy link

oncicaradupopovici commented Nov 20, 2017

I was very sad to retest this issue on 2.0.1 and got the same exception.
@ajcvickers can you please tell us when will this fix be included in a stable release?

@ajcvickers
Copy link
Member

@oncicaradupopovici The milestone assigned at the top of the issue is the indicator of what release a fix will be in--in this case 2.1. Unfortunately, the dates for 2.1 are not confirmed yet, so I can't share them publicly at this time.

@brendanalexdr
Copy link

@oncicaradupopovici yes I was disappointed to discover the same thing after installing 2.0.1

@xucito
Copy link

xucito commented Mar 20, 2018

Anyone who is still looking at this, if you have multiple DbContext and want to implement the Pool for only one, place the DbContextPool as the last added context it appears to work and not throw the error.

 services.AddDbContext<ADbContext>(options => options.UseNpgsql(connectionA); );

 services.AddDbContext<BDbContext>(options => options.UseNpgsql(connectionB));

services.AddDbContextPool<CDbContext>(options => options.UseNpgsql(connectionC));

Might be a useful workaround for some.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. type-bug
Projects
None yet
Development

No branches or pull requests

10 participants