Контекстные конструкторы при реализации DbContextPooling и Code-First Db Migrations - PullRequest
0 голосов
/ 02 июля 2019

Во-первых, я прошу прощения за заголовок на этом.Я не совсем уверен, как это описать.

В одном из наших проектов MVC мы используем AddDbContextPool, используя наш пользовательский контекст, в котором есть один конструктор, принимающий единственный параметр DbContextOptions.Все прекрасно работает, когда в контексте есть такой конструктор.

Однако, чтобы выполнить миграцию БД, в контексте потребовался пустой конструктор (насколько я знаю).

Если я помещу это обратно в контекст, тогда мой проект MVC начнет получать:

Невозможно объединить DbContext типа 'DbContext', так как он не имеет ни одного общедоступного конструктора, принимающегоодин параметр типа DbContextOptions

И если у меня нет пустого конструктора в контексте, я не могу сгенерировать новую миграцию БД.

Итак, кто-нибудь знает оспособ заставить это все хорошо поиграть друг с другом?Как выполнить миграцию с пользовательским контекстом, в котором есть один конструктор, принимающий параметр типа DbContextOptions?Или как мне иметь несколько конструкторов, сохраняя работоспособность моего DbContextPooling?

1 Ответ

0 голосов
/ 02 июля 2019

Однако, чтобы выполнить миграцию БД, в контексте потребовался пустой конструктор (насколько я знаю).

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

EF Core предназначен для внедрения зависимостей. If ожидает, что DbContextOptions будет предоставлено через внедрение зависимостей. Тем не менее, при запуске команд из командной строки ваше приложение, вероятно, не работает, и даже если бы это было так, на самом деле нет никакого способа каким-либо образом удаленно войти в его набор служб для получения необходимой информации. В результате EF Core компенсирует один из двух способов:

  1. Если проект, с которым запускается команда, является стартовым проектом (буквально это не обязательно должен быть стартовый проект - просто проект, который может запустить ), тогда EF фактически запустит Program, чтобы получить доступ к этому набору сервисов, вытянув оттуда DbContext, точно так же, как любая другая обычная инъекция DbContext будет работать.

  2. Однако, если проект похож на библиотеку классов, он не может этого сделать. В этом сценарии вы можете передать его на запуск, в дополнение к проекту, на который вы мигрируете. Если вы сделаете это, он работает в основном так же, как # 1 выше. Если не считать этого, ему нужен какой-то другой способ узнать, что делать ...

Что подводит нас к этому другому пути. Есть интерфейс под названием IDesignTimeDbContextFactory. Если реализация проекта этого интерфейса существует в проекте, против которого переносится EF Core, он будет использовать его для получения контекста. Типичная реализация будет выглядеть так:

public class MyDbContextFactory : IDesignTimeDbContextFactory<MyDbContext>
{
    public MyDbContext CreateDbContext(string[] args)
    {
        var options = new DbContextOptionsBuilder<MyDbContext>()
            .UseSqlServer("[connection string here]")
            .Options;

        return new MyDbContext(options);
    }
}

Помимо

Строка соединения по большей части должна быть жестко запрограммирована. Люди, как правило, немного сходят с ума здесь и пытаются настроить целую параллельную конфигурацию, и это по большей части не нужно. Как видно из названия интерфейса, это для разработки. Эта реализация не должна выполняться в любой другой среде, поэтому нет никаких оснований для настройки параметров среды. Кроме того, строка соединения для разработки обычно может быть создана не зависящим от разработчика способом, поэтому обычно нет необходимости переходить от одного разработчика к другому. Если вам нужно do , просто загрузите провайдер конфигурации User Secrets, чтобы отдельные разработчики могли определять свои собственные строки подключения оттуда.

...