简体   繁体   English

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

[英]How to have multiple DbContext of the same type?

I want to do some reporting in a ASP.NET Core web site that reads data from multiple databases using the same schema. 我想在ASP.NET Core网站上进行一些报告,该网站使用相同的架构从多个数据库中读取数据。

In Startup.cs I need to have something like: 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")));

}

But now the DbContext are of the same type and have no name, so how do I select the one I want to use in a controller? 但是,现在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;
    }

}

EDIT: 编辑:

I'm probably missing something but in MyContext I have: 我可能丢失了一些东西,但是在MyContext我有:

public class MyContext : DbContext
{

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

    // Some more code here.

}

Then in MyContext1 I have: 然后在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)
    {
    }

}

If I add 2 derived types in startup and run it crashes and gives the following error message: 如果我在启动时添加2个派生类型并运行,它会崩溃并给出以下错误消息:

InvalidOperationException: Unable to resolve service for type 'Microsoft.EntityFrameworkCore.DbContextOptions`1[MyContext]' while attempting to activate 'MyContext1'.

If I also add the base type in startup (so 3 types with 3 different connection strings) then all 3 types use the connection string of the base type. 如果我还在启动时添加基本类型(因此3种类型具有3个不同的连接字符串),那么所有3种类型都将使用基本类型的连接字符串。

Why not just create two DbContexts? 为什么不只创建两个DbContext? In theory, making 3 is probably cleaner .. keep the MyContext that you have set up, and then just create a Db1Context and Db2Context that inherit from it? 从理论上讲,使3可能更干净..保留您设置的MyContext,然后仅创建一个从其继承的Db1Context和Db2Context? means your registration ends up as 表示您的注册最终为

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

so then its easy to resolve, and due to inheritance you avoid some code duplication.. but I see no benefit from trying to keep 1 dbcontext that goes to multiple db in the same app 因此,它很容易解决,并且由于继承,您避免了一些代码重复..但我认为尝试将1个dbcontext保留到同一应用程序中的多个db并没有任何好处

Edit: If you are still having some troubles with DI working, there was a fairly old thread on the Github that looks like someone having this type of issue which they resolved by doing 编辑:如果您在使用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) { }
    }

something along those lines, having a second protected constructor in the class that inherits from dbcontext, to allow for the further inherited classes to use that. 遵循这些原则,在类中从dbcontext继承了第二个受保护的构造函数,以允许其他继承的类使用它。 I mean, I wasnt able to re-create the issue on my end but that solution still also works for me, so may help in terms of getting it working for you 我的意思是,我无法重新创建问题,但该解决方案仍然对我有用,因此可能对您有所帮助

I'm creating the multiple contexts in my reporting controllers in the end. 最后,我将在报表控制器中创建多个上下文。 It's not the DI way, but it works. 这不是DI的方式,但是有效。

I have something like the following code in the controller constructor: 我在控制器构造函数中有类似以下代码的内容:

var firstOptionsBuilder = new DbContextOptionsBuilder<MyContext>();
firstOptionsBuilder.UseSqlServer("firstConnectionString");
var firstContext = new MyContext(firstOptionsBuilder.Options);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM