如何拥有多个相同类型的DbContext?

Sac*_*a K 2 c# entity-framework-core asp.net-core

我想在 ASP.NET Core 网站中执行一些报告,该网站使用相同的架构从多个数据库读取数据。

Startup.cs需要有类似的东西:

public void ConfigureServices(IServiceCollection services)
{

// Some other stuff here.

services.AddDbContext<MyContext>(options => options.UseSqlServer(Configuration.GetConnectionString("FirstConnectionString")));
services.AddDbContext<MyContext>(options => options.UseSqlServer(Configuration.GetConnectionString("SecondConnectionString")));

}
Run Code Online (Sandbox Code Playgroud)

但现在 DbContext 是同一类型并且没有名称,那么如何选择我想要在控制器中使用的 DbContext?

public class HomeController : Controller
{

    private readonly MyContext context;

    public HomeController(MyContext context)
    {
        // Is that the one with FirstConnectionString or SecondConnectionString?
        // How do I choose?
        this.context = context;
    }

}
Run Code Online (Sandbox Code Playgroud)

编辑:

我可能错过了一些东西,但MyContext我有:

public class MyContext : DbContext
{

    public MyContext(DbContextOptions<MyContext> options) : base(options)
    {
    }

    // Some more code here.

}
Run Code Online (Sandbox Code Playgroud)

然后MyContext1我有:

public class MyContext1 : MyContext
{

    // base in now MyContext and not DbContext !!!
    // Error with: public MyContext1(DbContextOptions<MyContext1> options) : base(options)
    public MyContext1(DbContextOptions<MyContext> options) : base(options)
    {
    }

}
Run Code Online (Sandbox Code Playgroud)

如果我在启动时添加 2 个派生类型并运行,它会崩溃并给出以下错误消息:

InvalidOperationException: Unable to resolve service for type 'Microsoft.EntityFrameworkCore.DbContextOptions`1[MyContext]' while attempting to activate 'MyContext1'.
Run Code Online (Sandbox Code Playgroud)

如果我还在启动中添加基本类型(因此 3 种类型具有 3 个不同的连接字符串),那么所有 3 种类型都使用基本类型的连接字符串。

Gib*_*bon 5

为什么不直接创建两个 DbContext?理论上,制作 3 可能更干净..保留您设置的 MyContext,然后创建一个继承它的 Db1Context 和 Db2Context ?意味着您的注册最终为

services.AddDbContext<Db1Context>(options => options.UseSqlServer(Configuration.GetConnectionString("FirstConnectionString")));
services.AddDbContext<Db2Context>(options => options.UseSqlServer(Configuration.GetConnectionString("SecondConnectionString")));
Run Code Online (Sandbox Code Playgroud)

所以它很容易解决,并且由于继承,您可以避免一些代码重复..但我认为尝试保留 1 个 dbcontext 进入同一个应用程序中的多个数据库没有任何好处

编辑:如果您在 DI 工作方面仍然遇到一些问题,Github 上有一个相当旧的线程,看起来有人遇到了此类问题,他们通过执行以下操作解决了

public class EFDbContext : DbContext
    {
        public EFDbContext(DbContextOptions<EFDbContext> options) : base(options) { }
        protected MainDbContext(DbContextOptions options) : base(options) { }
    }

public class DimensionsDbContext : EFDbContext
    {
        public DimensionsDbContext(DbContextOptions<DimensionsDbContext> options) : base(options) { }
    }
Run Code Online (Sandbox Code Playgroud)

沿着这些思路,在继承自 dbcontext 的类中具有第二个受保护的构造函数,以允许进一步继承的类使用它。我的意思是,我无法重新创建问题,但该解决方案仍然适用于我,因此可能有助于让它为您工作