如何使用多DBContextPool?

时间:2017-08-16 06:04:13

标签: entity-framework-core

在EFCore 2.0中添加新功能,DbContext池。 我知道如何在单一环境中使用它, 但是,有时在项目中需要多个上下文,

public class BContext : DbContext
{
    public BContext(DbContextOptions<BContext> options) : base(options) { }
}

public class AContext : DbContext
{
    public AContext(DbContextOptions<AContext> options) : base(options) { }
}

ConfigureServices

services.AddDbContextPool<AContext>(options =>
{
    options.UseInMemoryDatabase("AContext.InMemory");
});
services.AddDbContextPool<BContext>(options =>
{
    options.UseInMemoryDatabase("BContext.InMemory");
});

控制器

public class HomeController : Controller
{
    private readonly AContext aContext;

    public HomeController(AContext aContext)
    {
        this.aContext = aContext;
    }

    public IActionResult Index()
    {
        return View();
    }
}

当我使用任何上下文时,抛出异常。

  

System.ArgumentException:类型&#39; Microsoft.EntityFrameworkCore.DbContextOptions`1 [MultiContext.Contexts.BContext]&#39;的表达式不能用于类型&#39; Microsoft.EntityFrameworkCore.DbContextOptions`1 [MultiContext.Contexts.AContext]&#39;的构造函数参数。   参数名称:arguments [0]      at System.Dynamic.Utils.ExpressionUtils.ValidateOneArgument(MethodBase方法,ExpressionType nodeKind,Expression参数,ParameterInfo pi,String methodParamName,String argumentParamName,Int32 index)      at System.Dynamic.Utils.ExpressionUtils.ValidateArgumentTypes(MethodBase方法,ExpressionType nodeKind,ReadOnlyCollection`1&amp; arguments,String methodParamName)      在System.Linq.Expressions.Expression.New(ConstructorInfo构造函数,IEnumerable`1参数)      在System.Linq.Expressions.Expression.New(ConstructorInfo构造函数,Expression []参数)      在Microsoft.EntityFrameworkCore.Internal.DbContextPool`1.CreateActivator(DbContextOptions选项)      在Microsoft.EntityFrameworkCore.Internal.DbContextPool`1..ctor(DbContextOptions选项)   ---从抛出异常的先前位置开始的堆栈跟踪结束---      在System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()      在Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite,ServiceProvider provider)      在Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite,TArgument参数)      在Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite,ServiceProvider provider)      在Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitSingleton(SingletonCallSite singletonCallSite,ServiceProvider provider)      在Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite,TArgument参数)      在Microsoft.Extensions.DependencyInjection.ServiceProvider。&lt;&gt; c__DisplayClass22_0.b__0(ServiceProvider provider)      在Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(类型serviceType)      在Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetService [T](IServiceProvider提供程序)      在Microsoft.Extensions.DependencyInjection.EntityFrameworkServiceCollectionExtensions。&lt;&gt; c__2`1.b__2_1(IServiceProvider p)      在Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite,ServiceProvider provider)      在Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite,TArgument参数)      在Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite,ServiceProvider provider)      在Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite,TArgument参数)      在Microsoft.Extensions.DependencyInjection.ServiceProvider。&lt;&gt; c__DisplayClass22_0.b__0(ServiceProvider provider)      在Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(类型serviceType)      在Microsoft.Extensions.Internal.ActivatorUtilities.GetService(IServiceProvider sp,Type type,Type requiredBy,Boolean isDefaultParameterRequired)      在lambda_method(Closure,IServiceProvider,Object [])      在Microsoft.AspNetCore.Mvc.Controllers.ControllerActivatorProvider。&lt;&gt; c__DisplayClass4_0.b__0(ControllerContext controllerContext)      在Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider。&lt;&gt; c__DisplayClass5_0.g__CreateController0(ControllerContext controllerContext)      在Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State&amp; next,Scope&amp; scope,Object&amp; state,Boolean&amp; isCompleted)      在Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.d__14.MoveNext()   ---从抛出异常的先前位置开始的堆栈跟踪结束---      在System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()      在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)      在Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.d__22.MoveNext()   ---从抛出异常的先前位置开始的堆栈跟踪结束---      在System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()      在Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)      在Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State&amp; next,Scope&amp; scope,Object&amp; state,Boolean&amp; isCompleted)      在Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.d__17.MoveNext()   ---从抛出异常的先前位置开始的堆栈跟踪结束---      在System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()      在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)      在Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.d__15.MoveNext()   ---从抛出异常的先前位置开始的堆栈跟踪结束---      在System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()      在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)      在Microsoft.AspNetCore.Builder.RouterMiddleware.d__4.MoveNext()   ---从抛出异常的先前位置开始的堆栈跟踪结束---      在System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()      在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)      在Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.d__7.MoveNext()

2 个答案:

答案 0 :(得分:2)

确定。我发现了问题。您需要下载EF Core,然后更改构造函数 DbContextPool&LT; TContext&GT;

原创

public DbContextPool([NotNull] DbContextOptions options)

并改为

public DbContextPool([NotNull] DbContextOptions<TContext> options)

否则DI将使用最后添加的选项:)

答案 1 :(得分:1)

或者您可以注册自己的DbContextPool工厂

services.AddDbContextPool<AContext>(options =>
{
    options.UseInMemoryDatabase("AContext.InMemory");
});
services.AddDbContextPool<BContext>(options =>
{
    options.UseInMemoryDatabase("BContext.InMemory");
});

collection.AddSingleton(svcs => new DbContextPool<AContext>(svcs.GetService<DbContextOptions<AContext>>()));
collection.AddSingleton(svcs => new DbContextPool<BContext>(svcs.GetService<DbContextOptions<BContext>>()));