Configuração baseada em códigoCode-based configuration

Observação

EF6 em diante apenas: os recursos, as APIs etc. discutidos nessa página foram introduzidos no Entity Framework 6.EF6 Onwards Only - The features, APIs, etc. discussed in this page were introduced in Entity Framework 6. Se você estiver usando uma versão anterior, algumas ou todas as informações não se aplicarão.If you are using an earlier version, some or all of the information does not apply.

Configuração de um aplicativo do Entity Framework pode ser especificada em um arquivo de configuração (app.config/web.config) ou por meio de código.Configuration for an Entity Framework application can be specified in a config file (app.config/web.config) or through code. A última opção é conhecida como configuração baseada em código.The latter is known as code-based configuration.

Configuração em um arquivo de configuração é descrita em uma artigo separado.Configuration in a config file is described in a separate article. O arquivo de configuração tem precedência sobre a configuração baseada em código.The config file takes precedence over code-based configuration. Em outras palavras, se uma opção de configuração está definida no código e no arquivo de configuração, a configuração no arquivo de configuração é usada.In other words, if a configuration option is set in both code and in the config file, then the setting in the config file is used.

Usando DbConfigurationUsing DbConfiguration

Configuração baseada em código no EF6 e superior é obtida com a criação de uma subclasse de System.Data.Entity.Config.DbConfiguration.Code-based configuration in EF6 and above is achieved by creating a subclass of System.Data.Entity.Config.DbConfiguration. As diretrizes a seguir devem ser seguidas ao subclasses DbConfiguration:The following guidelines should be followed when subclassing DbConfiguration:

  • Crie apenas uma classe DbConfiguration para seu aplicativo.Create only one DbConfiguration class for your application. Essa classe especifica configurações de domínio de aplicativo.This class specifies app-domain wide settings.
  • Coloque sua classe DbConfiguration no mesmo assembly que sua classe DbContext.Place your DbConfiguration class in the same assembly as your DbContext class. (Consulte a DbConfiguration movendo seção se você quiser alterar isso.)(See the Moving DbConfiguration section if you want to change this.)
  • Fornecer um construtor público sem parâmetros de sua classe DbConfiguration.Give your DbConfiguration class a public parameterless constructor.
  • Definir opções de configuração chamando os métodos protegidos DbConfiguration, de dentro desse construtor.Set configuration options by calling protected DbConfiguration methods from within this constructor.

As diretrizes a seguir permite que o EF descubram e usem sua configuração automaticamente por ambas as ferramentas que precisa acessar o seu modelo e quando seu aplicativo é executado.Following these guidelines allows EF to discover and use your configuration automatically by both tooling that needs to access your model and when your application is run.

ExemploExample

Uma classe derivada de DbConfiguration pode ter esta aparência:A class derived from DbConfiguration might look like this:

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"));
        }
    }
}

Essa classe define EF para usar a estratégia de execução do SQL Azure - para repetir automaticamente as operações de banco de dados com falha - e usar o banco de dados Local para bancos de dados que são criados por convenção do Code First.This class sets up EF to use the SQL Azure execution strategy - to automatically retry failed database operations - and to use Local DB for databases that are created by convention from Code First.

Movendo DbConfigurationMoving DbConfiguration

Há casos em que não é possível colocar sua classe DbConfiguration no mesmo assembly como sua classe DbContext.There are cases where it is not possible to place your DbConfiguration class in the same assembly as your DbContext class. Por exemplo, você pode ter duas classes DbContext cada em diferentes assemblies.For example, you may have two DbContext classes each in different assemblies. Há duas opções para lidar com isso.There are two options for handling this.

A primeira opção é usar o arquivo de configuração para especificar a instância DbConfiguration usar.The first option is to use the config file to specify the DbConfiguration instance to use. Para fazer isso, defina o atributo codeConfigurationType da seção entityFramework.To do this, set the codeConfigurationType attribute of the entityFramework section. Por exemplo:For example:

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

O valor de codeConfigurationType deve ser o assembly e o nome qualificado do namespace da sua classe DbConfiguration.The value of codeConfigurationType must be the assembly and namespace qualified name of your DbConfiguration class.

A segunda opção é colocar DbConfigurationTypeAttribute em sua classe de contexto.The second option is to place DbConfigurationTypeAttribute on your context class. Por exemplo:For example:

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

O valor passado para o atributo pode ser seu tipo DbConfiguration - conforme mostrado acima - ou o assembly e namespace qualificado a cadeia de caracteres de nome de tipo.The value passed to the attribute can either be your DbConfiguration type - as shown above - or the assembly and namespace qualified type name string. Por exemplo:For example:

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

Configurar DbConfiguration explicitamenteSetting DbConfiguration explicitly

Há algumas situações em que configurações podem ser necessárias antes de qualquer tipo DbContext tem sido usado.There are some situations where configuration may be needed before any DbContext type has been used. Exemplos incluem:Examples of this include:

  • Usando DbModelBuilder para criar um modelo sem contextoUsing DbModelBuilder to build a model without a context
  • Usando algum outro código de framework/utilitário que utiliza um DbContext em que esse contexto é usado antes de seu contexto de aplicativo é usadoUsing some other framework/utility code that utilizes a DbContext where that context is used before your application context is used

Em tais situações EF não conseguir descobrir a configuração automaticamente e, em vez disso, você deve fazer o seguinte:In such situations EF is unable to discover the configuration automatically and you must instead do one of the following:

  • Defina o tipo de DbConfiguration no arquivo de configuração, conforme descrito na DbConfiguration movendo seção acimaSet the DbConfiguration type in the config file, as described in the Moving DbConfiguration section above
  • Chame o método DbConfiguration.SetConfiguration estático durante a inicialização do aplicativoCall the static DbConfiguration.SetConfiguration method during application startup

Substituindo DbConfigurationOverriding DbConfiguration

Há algumas situações em que você precisa substituir a configuração definida no DbConfiguration.There are some situations where you need to override the configuration set in the DbConfiguration. Isso não é normalmente feito por desenvolvedores de aplicativos, mas em vez disso, por provedores de terceiros e plug-ins que não é possível usar uma classe derivada de DbConfiguration.This is not typically done by application developers but rather by third party providers and plug-ins that cannot use a derived DbConfiguration class.

Para isso, o EntityFramework permite que um manipulador de eventos a ser registrado que pode modificar a configuração existente antes que ele é bloqueado.For this, EntityFramework allows an event handler to be registered that can modify existing configuration just before it is locked down. Ele também fornece um método de açúcar especificamente para a substituição de qualquer serviço retornado pelo localizador de serviço do EF.It also provides a sugar method specifically for replacing any service returned by the EF service locator. Isso é como ele se destina a ser usado:This is how it is intended to be used:

  • Na inicialização do aplicativo (antes do EF é usado) o plug-in ou o provedor deve se registrar para o método de manipulador de eventos para este evento.At app startup (before EF is used) the plug-in or provider should register the event handler method for this event. (Observe que isso deve ocorrer antes que o aplicativo usa o EF).(Note that this must happen before the application uses EF.)
  • O manipulador de eventos faz uma chamada para replaceservice tenha para cada serviço que precisa ser substituído.The event handler makes a call to ReplaceService for every service that needs to be replaced.

Por exemplo, para substituir IDbConnectionFactory e DbProviderService você poderia registrar um manipulador algo assim:For example, to replace IDbConnectionFactory and DbProviderService you would register a handler something like this:

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

No código acima MyProviderServices e MyConnectionFactory representam suas implementações do serviço.In the code above MyProviderServices and MyConnectionFactory represent your implementations of the service.

Você também pode adicionar manipuladores de dependência adicional para obter o mesmo efeito.You can also add additional dependency handlers to get the same effect.

Observe que você pode também encapsular DbProviderFactory dessa maneira, mas fazer então afetará apenas EF e não os usos do DbProviderFactory fora do EF.Note that you could also wrap DbProviderFactory in this way, but doing so will only affect EF and not uses of the DbProviderFactory outside of EF. Por esse motivo provavelmente você desejará continuar a encapsular o DbProviderFactory quando você tem antes.For this reason you’ll probably want to continue to wrap DbProviderFactory as you have before.

Você também deve ter em mente os serviços que são executados externamente para seu aplicativo - por exemplo, ao executar migrações no Console do Gerenciador de pacote.You should also keep in mind the services that you run externally to your application - for example, when running migrations from the Package Manager Console. Quando você executa migre do console, que ele tentará localizar seu DbConfiguration.When you run migrate from the console it will attempt to find your DbConfiguration. No entanto, se deseja ou não obterá o serviço encapsulado depende de onde o manipulador de eventos registrado por ele.However, whether or not it will get the wrapped service depends on where the event handler it registered. Se ele estiver registrado como parte da construção do seu DbConfiguration, em seguida, o código deve ser executado e o serviço deve obter encapsulado.If it is registered as part of the construction of your DbConfiguration then the code should execute and the service should get wrapped. Normalmente, isso não será o caso, e isso significa que as ferramentas não obterá o serviço encapsulado.Usually this won’t be the case and this means that tooling won’t get the wrapped service.