所以我很好奇,我有一个应用程序,它有一个内部网站和一个外部网站。 它们的db是相同的。 基本上,内部应用是让用户改变外部应用上显示的数据。 所以为此,我决定为app创建一个单一的db上下文,用于内部db的连接。 然后,我为外部连接创建了另一个从内部上下文继承的上下文,我这样做是因为我认为我可以将它们添加到服务中,并将每个上下文设置为它自己的数据库。 当我把它们注入到我的promoter类中时,两个db连接都指向同一个db。 为什么会这样? 所以我的contexts是这样的。
public class AppContext : DbContext
{
public AppContext() { }
public AppContext(DbContextOptions<AppContext> options): base(options)
{ }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Folder.Folder>().ToTable("Folders");
modelBuilder.Entity<File.File>().ToTable("Files");
modelBuilder.Entity<DocumentView>().ToTable("DocumentViews")
.HasKey(c=> new { c.PersonId, c.DocId });
modelBuilder.Entity<AppInfo>().ToTable("AppInfo");
}
public DbSet<Folder.Folder> Folders { get; set; }
public DbSet<File.File> Files { get; set; }
public DbSet<DocumentView> DocumentViews { get; set; }
public DbSet<AppInfo> AppInfos { get; set; }
}
public class ExternalAppContext : AppContext
{
public ExternalAppContext(DbContextOptions<AppContext> options) : base(options)
{ }
}
当我在启动过程中注册他们时,我把他们注册成这样。
services.AddDbContext<AppContext>(options => options.UseSqlite(@"Data Source=" + Configuration["SqlConnection:adminDbLocation"]));
services.AddDbContext<ExternalAppContext>(options => options.UseSqlite(@"Data Source=" + Configuration["SqlConnection:externalDbLocation"]))
推广器类注入是。
public Promoter(ExternalAppContext externalContext, AppContext adminContext)
{
_externalContext = externalContext;
_adminContext = adminContext;
}
所以这里真正的答案是嵌在三年前的一个github答案里,可以找到的 https:/github.comdotnetefcoreissues7533。. 这个问题归根结底是服务如何被呈现为池,这就是为什么当注册多个DbContexts时,你必须在DbContextOptions上指定类型。 为了绕过这个问题,你可以在基类中为选项设置一个保护的构造函数。 这将允许池化正确工作,并允许你继承上下文。 greggbjensen在2017年12月给出的例子如下,正是我所寻找的。
public class MainDbContext : DbContext
{
public MainDbContext(DbContextOptions<MainDbContext> options)
: base(options)
{
}
protected MainDbContext(DbContextOptions options)
: base(options)
{
}
}
public class SubDbContext : MainDbContext
{
public SubDbContext (DbContextOptions<SubDbContext> options)
: base(options)
{
}
}
这样就可以在.net核心服务代码中设置两个服务,是这样的。
services.AddDbContext<MainDbContext >(options => [[SomeOptionsHere]]);
services.AddDbContext<SubDbContext >(options => [[SomeOptionsHere]]);