我想在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")));
}
但是现在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;
}
}
编辑:
我可能缺少一些东西,但是在MyContext
中,我有
public class MyContext : DbContext
{
public MyContext(DbContextOptions<MyContext> options) : base(options)
{
}
// Some more code here.
}
然后在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)
{
}
}
如果我在启动时添加2个派生类型并运行它会崩溃,并显示以下错误消息:
InvalidOperationException: Unable to resolve service for type 'Microsoft.EntityFrameworkCore.DbContextOptions`1[MyContext]' while attempting to activate 'MyContext1'.
如果我还在启动时添加了基本类型(因此3种类型具有3个不同的连接字符串),那么所有3种类型都将使用基本类型的连接字符串。
答案 0 :(得分:3)
为什么不仅仅创建两个DbContext?从理论上讲,使3可能更干净..保留您设置的MyContext,然后仅创建一个从其继承的Db1Context和Db2Context?表示您的注册以
结尾services.AddDbContext<Db1Context>(options => options.UseSqlServer(Configuration.GetConnectionString("FirstConnectionString")));
services.AddDbContext<Db2Context>(options => options.UseSqlServer(Configuration.GetConnectionString("SecondConnectionString")));
因此它很容易解决,并且由于继承,您避免了一些代码重复..但是我发现尝试将1个dbcontext保留到同一应用程序中的多个db并没有任何好处
编辑: 如果您在使用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) { }
}
遵循这些原则,在从dbcontext继承的类中具有第二个受保护的构造函数,以允许其他继承的类使用它。我的意思是,我最终无法重新创建该问题,但是该解决方案仍然对我有用,因此可能对您有所帮助
答案 1 :(得分:0)
最后,我将在报表控制器中创建多个上下文。这不是DI方式,但是可以。
我在控制器构造函数中有类似以下代码的内容:
var firstOptionsBuilder = new DbContextOptionsBuilder<MyContext>();
firstOptionsBuilder.UseSqlServer("firstConnectionString");
var firstContext = new MyContext(firstOptionsBuilder.Options);