簡體   English   中英

如何在 controller 中使用多個 DBContext

[英]How to use more than one DBContext in a controller

如何在 controller 中使用多個 DBContext,我試圖以不同的方式重載 construktors?

一些 Controller:

public C1(DBContext1 a, DBContext2 b, DBContext3 c)
{ 
}
 //public C1(DBContext1 a)
 //{ 
 //}
 //public C1(DBContext2 b)
 //{
 //}
 //public C1(DBContext3 c)
 //{
 //}

啟動.cs:

services.AddDbContext<DBContext1>(options =>
options.UseSqlServer(new string(K.ConnectionString))
);

services.AddDbContext<DBContext2>(options =>
options.UseSqlServer(new string(K.ConnectionString))
);

services.AddDbContext<DBContext3>(options =>
options.UseSqlServer(new string(K.ConnectionString))
);

我找到了這個,但它似乎已經過時了

錯誤(,當前端調用構造函數時):

執行請求時發生未處理的異常。

異常:System.InvalidOperationException:傳遞給 DBContext1 構造函數的 DbContextOptions 必須是 DbContextOptions。 注冊多個 DbContext 類型時,請確保每個上下文類型的構造函數都具有 DbContextOptions 參數,而不是非泛型 DbContextOptions 參數。 在 Microsoft.EntityFrameworkCore.DbContext..ctor(DbContextOptions options) at _4_DWH.DBContext1..ctor(DbContextOptions options) 在 D:...\DBContext1.cs:line 43 at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments,簽名 sig,Boolean 構造函數,Boolean wrapExceptions) 在 System.Reflection.RuntimeCultureConstructorInfo.Invoke,Object[BindingFlag]
在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context) 在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor 2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor 2.VisitCallSite(ServiceCallSite callSite, TArgument 參數)在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope) 在 Mic rosoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.b__0(ServiceProviderEngineScope 范圍)在 Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(類型 serviceType,ServiceProviderEngineScope serviceProviderEngineScope)
在 Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(類型 serviceType) 在 Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp,類型類型,類型 requiredBy,Boolean isDefaultParameterRequired)
在 lambda_method(Closure, IServiceProvider, Object[] ) 在 Microsoft.AspNetCore.Mvc.Controllers.ControllerActivatorProvider.<>c__DisplayClass4_0.b__0(ControllerContext controllerContext) 在 Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider.<>c__DisplayClass5_0.g__CreateController|0( ControllerContext controllerContext) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync() --- End of stack trace from previous location where exception was thrown --- at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Z27226C 864BAC7454A8504F8EDB15D95BZ isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc .Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync() --- 從先前引發異常的位置結束堆棧跟蹤 --- 在 Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker 調用程序,任務任務,IDisposable 范圍) Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(端點端點,任務 requestTask,ILogger 記錄器)在 Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.MigrationsEndPointMiddleware.Invoke(HttpContext context)在 Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.Invoke( HttpContext httpContext) 在 Microsoft.Asp NetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.Invoke(HttpContext httpContext) 在 Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

數據庫上下文:

public class DBContext1 : DbContext
{
    // ...

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(new string(sameConnectionString));
    }

    public DBContext1() : base()
    {

    }

    public DBContext1(DbContextOptions options) : base(options)
    {
    }
}
  1. 創建數據庫上下文
public class DBContext_A : DbContext
{
    public DBContext_A(DbContextOptions<DBContext_A> options) : base(options)
    {
    }
}

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

public class DBContext_C : DbContext
{
    public DBContext_C(DbContextOptions<DBContext_C> options) : base(options)
    {
    }
}
  1. 為每個 DBContext 定義一個連接字符串:
{
  "ConnectionStrings": {
    "Connection_A": "Server=(localdb)\\mssqllocaldb;Database=DB_A;Trusted_Connection=True;...",
    "Connection_B": "Server=(localdb)\\mssqllocaldb;Database=DB_B;Trusted_Connection=True;...",
    "Connection_C": "Server=(localdb)\\mssqllocaldb;Database=DB_C;Trusted_Connection=True;...",
  }
}
  1. 在啟動時注冊:
services.AddDbContext<DBContext_A>(ops =>
{
    ops.UseSqlServer(Configuration.GetConnectionString($"Connection_A"));
});

services.AddDbContext<DBContext_B>(ops =>
{
    ops.UseSqlServer(Configuration.GetConnectionString($"Connection_B"));
});

services.AddDbContext<DBContext_C>(ops =>
{
    ops.UseSqlServer(Configuration.GetConnectionString($"Connection_C"));
});

  1. 注入 controller:
public FooController : Controller
{
    private readonly DBContext_A _context_A;
    private readonly DBContext_B _context_B;
    private readonly DBContext_C _context_C;

    public FooController(
            DBContext_A context_A, 
            DBContext_B context_B, 
            DBContext_C context_C)
    {
        _context_A = context_A;
        _context_B = context_B;
        _context_C = context_C;
    }
}

Code First 方法的其他最佳實踐:

為每個上下文創建一個 class 庫,因此當您應用遷移時,每個上下文將在其自己的項目中擁有自己的遷移文件夾。

  • 解決方案
    • 主要項目
      • 啟動.cs
    • 類庫_A
      • DbContext_A.cs
      • 遷移 // 文件夾
    • 類庫_B
      • DbContext_B.cs
      • 遷移 // 文件夾
    • 類庫_C
      • DbContext_C.cs
      • 遷移 // 文件夾

在多上下文解決方案中應用遷移時;

  • 從解決方案資源管理器中,將主項目(使用 startup.cs)設置為“啟動項目”
  • 將 package 管理器控制台中的相關 ClassLibrary_A 或 B 或 C 設置為“默認項目”
  • 將目標上下文添加到每個 cmd 如下:
PM > add-migration Init -Context DBContext_A
PM > update-database -Context DBContext_A

PM > add-migration Init -Context DBContext_B
PM > update-database -Context DBContext_B

PM > add-migration Init -Context DBContext_C
PM > update-database -Context DBContext_C

或者,您可以使用完整的 PM cmd,如下所示:

PM > add-migration Init -Context DBContext_A -Project ClassLibrary_A -StartupProject MainProject
PM > update-database -Context DBContext_A -Project ClassLibrary_A -StartupProject MainProject

PM > add-migration Init -Context DBContext_B -Project ClassLibrary_B -StartupProject MainProject
PM > update-database -Context DBContext_B -Project ClassLibrary_B -StartupProject MainProject

PM > add-migration Init -Context DBContext_C -Project ClassLibrary_C -StartupProject MainProject
PM > update-database -Context DBContext_C -Project ClassLibrary_C -StartupProject MainProject

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM