Конфигурация на основе кода

Замечание

EF6 и более поздние версии — функции, API и т. д., рассмотренные на этой странице, были представлены в Entity Framework 6. Если вы используете более раннюю версию, некоторые или все сведения не применяются.

Конфигурацию для приложения Entity Framework можно указать в файле конфигурации (app.config/web.config) или с помощью кода. Последний называется конфигурацией на основе кода.

Конфигурация в файле конфигурации описана в отдельной статье. Файл конфигурации имеет приоритет над конфигурацией на основе кода. Другими словами, если параметр конфигурации задан как в коде, так и в файле конфигурации, используется параметр в файле конфигурации.

С использованием DbConfiguration

Конфигурация на основе кода в EF6 и выше достигается путем создания подкласса System.Data.Entity.Config.DbConfiguration. При создании подклассов DbConfiguration нужно соблюдать следующие рекомендации:

  • Создайте только один DbConfiguration класс для приложения. Этот класс задает параметры уровня домена приложения.
  • Поместите класс DbConfiguration в ту же сборку, что и класс DbContext. (См. раздел "Перемещение DbConfiguration ", если вы хотите изменить это.)
  • DbConfiguration Предоставьте классу открытый конструктор без параметров.
  • Задайте параметры конфигурации путем вызова защищенных DbConfiguration методов из этого конструктора.

Следуя этим рекомендациям, EF сможет автоматически обнаруживать и использовать вашу конфигурацию как инструментами для доступа к модели, так и при запуске приложения.

Пример

Класс, производный от DbConfiguration, может выглядеть следующим образом:

using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.SqlServer;

namespace MyNamespace
{
    public class MyConfiguration : DbConfiguration
    {
        public MyConfiguration()
        {
            SetExecutionStrategy("System.Data.SqlClient", () => new SqlAzureExecutionStrategy());
            SetDefaultConnectionFactory(new LocalDbConnectionFactory("mssqllocaldb"));
        }
    }
}

Этот класс настраивает EF для использования стратегии выполнения SQL Azure для автоматического повтора операций базы данных при сбоях и использования Local DB для баз данных, созданных по соглашению Code First.

Перемещение DbConfiguration

Существуют случаи, когда невозможно разместить ваш DbConfiguration класс в той же сборке, что и ваш DbContext класс. Например, у вас может быть два DbContext класса в разных сборках. Существует два варианта для обработки этого.

Первый вариант — использовать файл конфигурации для указания используемого экземпляра DbConfiguration . Для этого задайте атрибут codeConfigurationType раздела entityFramework. Рассмотрим пример.

<entityFramework codeConfigurationType="MyNamespace.MyDbConfiguration, MyAssembly">
    ...Your EF config...
</entityFramework>

Значение codeConfigurationType должно быть полным именем сборки и пространства имен класса DbConfiguration .

Второй вариант — поместить DbConfigurationTypeAttribute в класс контекста. Рассмотрим пример.

[DbConfigurationType(typeof(MyDbConfiguration))]
public class MyContextContext : DbContext
{
}

Значение, переданное атрибуту, может быть вашим DbConfiguration типом, как показано выше, или строкой с квалифицированным именем типа сборки и пространства имен. Рассмотрим пример.

[DbConfigurationType("MyNamespace.MyDbConfiguration, MyAssembly")]
public class MyContextContext : DbContext
{
}

Явное задание DbConfiguration

Существуют некоторые ситуации, когда конфигурация может потребоваться до использования любого DbContext типа. Ниже приведены примеры:

  • Использование DbModelBuilder для создания модели без контекста
  • Использование какого-либо другого кода платформы или служебной программы, в которой DbContext используется в этом контексте до использования контекста вашего приложения.

В таких ситуациях EF не может автоматически обнаруживать конфигурацию, и вместо этого необходимо выполнить одно из следующих действий:

  • DbConfiguration Задайте тип в файле конфигурации, как описано в разделе "ПеремещениеDbConfiguration" выше
  • Вызовите статический метод DbConfiguration.SetConfiguration во время запуска приложения

Переопределение DbConfiguration

В некоторых ситуациях необходимо переопределить набор конфигурации, установленный в DbConfiguration. Обычно это не делается разработчиками приложений, а сторонними поставщиками и подключаемыми модулями, которые не могут использовать производный DbConfiguration класс.

Для этого EntityFramework позволяет зарегистрировать обработчик событий, который может изменить существующую конфигурацию непосредственно перед блокировкой. Он также предоставляет упрощённый метод специально для замены любого сервиса, возвращаемого локатором сервисов EF. Вот как оно предназначено для использования:

  • При запуске приложения (до использования EF) подключаемый модуль или поставщик должен зарегистрировать метод обработчика событий для этого события. (Обратите внимание, что это должно произойти, прежде чем приложение использует EF.)
  • Обработчик событий вызывает ReplaceService для каждой службы, которую необходимо заменить.

Например, чтобы заменить IDbConnectionFactory и DbProviderService, вы бы зарегистрировали обработчик примерно так:

DbConfiguration.Loaded += (_, a) =>
   {
       a.ReplaceService<DbProviderServices>((s, k) => new MyProviderServices(s));
       a.ReplaceService<IDbConnectionFactory>((s, k) => new MyConnectionFactory(s));
   };

В приведенном выше коде MyProviderServices и MyConnectionFactory представляют ваши реализации службы.

Вы также можете добавить дополнительные обработчики зависимостей, чтобы получить тот же эффект.

Обратите внимание, что вы также можете завернуть DbProviderFactory таким образом, но это будет влиять только на EF, а не на использование DbProviderFactory вне EF. По этой причине вы, вероятно, хотите продолжать обертывать DbProviderFactory, как вы делали это раньше.

Кроме того, следует помнить о службах, которые вы выполняете вне приложения, например при выполнении миграции из консоли диспетчера пакетов. При выполнении миграции из консоли она попытается найти вашу DbConfiguration. Однако независимо от того, будет ли она получать упаковаемую службу, зависит от того, где он зарегистрирован обработчик событий. Если он зарегистрирован в рамках построения кода DbConfiguration , код должен выполняться, и служба должна быть упакована. Как правило, это не так, и это означает, что инструмент не получит упаковаемую службу.