Я хочу добавить пользовательскую строку подключения в свой контекст EF вместо использования строки подключения в моем web.config. Идея состоит в том, чтобы переместить всю логику, связанную с базой данных, из моего проекта MVC на отдельный слой. Я также хочу, чтобы этот слой отвечал за правильные строки подключения вместо моих веб-приложений.
В настоящее время службы, использующие контекст, вызывают конструктор по умолчанию:
using (var context = new MyDbContext()) {
//...
}
Конструктор по умолчанию внутренне вызывает DbContext
с именем строки подключения из web.config
:
public partial class MyDbContext : DbContext
{
public MyDbContext()
: base("name=MyDbContext")
{
}
//...
}
Чтобы внедрить мою пользовательскую строку подключения, мне понадобится перегруженный конструктор, который принимает строку подключения в качестве аргумента. К сожалению, такого конструктора не существует.
Очевидно, что добавление перегрузки конструктора вручную в классе MyDbContext
было бы очень плохой идеей, так как этот класс автогенерируется и будет перезаписан в ближайшее время. Позвольте больше не говорить об этом, это запрещено. Период.
Так как MyDbContext
является частичным классом, можно добавить дополнительный конструктор в отдельный файл класса partial class MyDbContext
, но это также кажется вонючим. Я не знаю, почему, но мой мозг говорит плохую идею.
После некоторого расследования я выяснил, что EF может включить этот дополнительный конструктор, отредактировав шаблон T4 Model.Context.tt
, который представляет собой сочетание С# и некоторой разметки шаблона. Вот оригинальный конструктор:
public <#=Code.Escape(container)#>()
: base("name=<#=container.Name#>")
{
<#
WriteLazyLoadingEnabled(container);
#>
}
Очевидно, легко добавить аналогичную логику для создания перегруженного конструктора, содержащего строку подключения:
public <#=Code.Escape(container)#>(string nameOrConnectionString)
: base(nameOrConnectionString)
{
<#
WriteLazyLoadingEnabled(container);
#>
}
Я попробовал это и заметил, что как повторное создание классов моделей, так и обновление модели из БД не повлияют на шаблон T4, поэтому всегда будет существовать дополнительный конструктор. Хорошо! На первый взгляд это выглядит как подходящее решение, но...
И вот мой вопрос: Это действительно хорошее решение?
Снова сравните три варианта:
- Отредактируйте автоматически сгенерированный класс (хорошо, мы договорились забыть об этом)
- Добавить конструктор в файл частичного класса
- Отредактируйте шаблон T4, чтобы сообщить EF о создании дополнительного конструктора
Из этих трех вариантов третий кажется мне самым удобным и чистым решением. Каково твое мнение? У кого-то есть веская причина, почему это было бы плохой идеей? Есть ли дополнительные возможности для ввода строк подключения, возможно, с помощью пользовательского connectionFactory
? Если да, то как мне это сделать?