Конфигурация на основе кода
Примечание.
Только в 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 для автоматического повтора операций базы данных сбоем и использования локальной базы данных для баз данных, созданных с помощью соглашения 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
, код должен выполняться, и служба должна быть упакована. Как правило, это не так, и это означает, что инструмент не получит упаковаемую службу.