Регистрация нескольких DBContexts в ядре. net с одним базовым классом - PullRequest
0 голосов
/ 04 мая 2020

Так что просто любопытство, у меня есть приложение, которое имеет внутренний сайт и внешний сайт. БД для них идентичен. По сути, внутреннее приложение предназначено для того, чтобы пользователи могли изменять данные, отображаемые во внешнем приложении. Поэтому для этого я решил создать единый контекст БД для приложения для внутреннего соединения БД. Затем я создал другой контекст, унаследованный от внутреннего, для внешнего соединения. Я сделал это, потому что подумал, что могу добавить их в службу и настроить каждый в свою собственную базу данных. Когда я внедряю их в свой класс промоутера, оба соединения БД указывают на один и тот же БД. Почему это? Итак, что у меня есть для моих контекстов:

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;
}

1 Ответ

1 голос
/ 04 мая 2020

Таким образом, настоящий ответ здесь был вложен в github-ответ за три года go, который можно найти https://github.com/dotnet/efcore/issues/7533. Проблема заключается в том, как предоставляются услуги для объединения в пул, поэтому при регистрации нескольких DbContexts необходимо указывать тип в DbContextOptions. Чтобы обойти это в базовом классе, вы можете иметь защищенный конструктор для опций. Это позволит пуле работать правильно и позволит вам наследовать контекст. Пример, приведенный greggbjensen для De c 2017, приведен ниже и был именно тем, что я искал.

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]]);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...