Как иметь несколько DbContext одного типа? - PullRequest
0 голосов
/ 05 марта 2019

Я хочу сделать несколько отчетов на веб-сайте 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 относится к тому же типу и не имеет имени, так как мне выбрать тот, который я хочу использовать в контроллере?

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:

Я, вероятно, что-то упускаю, но в 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 типа будут использовать строку подключения базового типа.

Ответы [ 2 ]

3 голосов
/ 05 марта 2019

Почему бы просто не создать два DbContexts? Теоретически, создание 3, вероятно, чище ... сохранить MyContext, который вы настроили, а затем просто создать Db1Context и Db2Context, которые наследуются от него? означает, что ваша регистрация заканчивается как

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

так что его легко разрешить, и благодаря наследованию вы избегаете некоторого дублирования кода ... но я не вижу никакой выгоды от попыток сохранить 1 dbcontext, который идет к нескольким дБ, в одном приложении

Edit: Если у вас все еще есть проблемы с работой 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, чтобы позволить дальнейшим унаследованным классам использовать это. Я имею в виду, что я не смог воссоздать проблему с моей стороны, но это решение все еще работает для меня, поэтому может помочь с точки зрения заставить его работать на вас

0 голосов
/ 07 марта 2019

В конце я создаю несколько контекстов в моих контроллерах отчетов.Это не способ DI, но он работает.

У меня есть что-то вроде следующего кода в конструкторе контроллера:

var firstOptionsBuilder = new DbContextOptionsBuilder<MyContext>();
firstOptionsBuilder.UseSqlServer("firstConnectionString");
var firstContext = new MyContext(firstOptionsBuilder.Options);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...