Compartir vía


Configuración basada en código

Nota:

Solo EF6 y versiones posteriores: las características, las API, etc. que se tratan en esta página se han incluido a partir de Entity Framework 6. Si usa una versión anterior, no se aplica parte o la totalidad de la información.

La configuración de una aplicación de Entity Framework se puede especificar en un archivo de configuración (app.config/web.config) o a través del código. Esta última opción se conoce como configuración basada en código.

La configuración en un archivo de configuración se describe en un artículo independiente. El archivo de configuración tiene prioridad sobre la configuración basada en código. Es decir, si se establece una opción de configuración en el código y en el archivo de configuración, se usa el valor del archivo de configuración.

Usar DbConfiguration

La configuración basada en código en EF6 y versiones posteriores se logra mediante la creación de una subclase de System.Data.Entity.Config.DbConfiguration. Se deben seguir las instrucciones siguientes al establecer subclases DbConfiguration:

  • Cree solo una clase DbConfiguration para la aplicación. Esta clase especifica la configuración de todo el dominio de la aplicación.
  • Coloque la clase DbConfiguration en el mismo ensamblado que la clase DbContext. (Consulte la sección Traslado de DbConfiguration si desea cambiar esto).
  • Asigne a la clase DbConfiguration un constructor público sin parámetros.
  • Establezca las opciones de configuración llamando a métodos DbConfiguration protegidos desde este constructor.

Al seguir estas instrucciones, EF puede detectar y utilizar su configuración automáticamente tanto por las herramientas que necesitan acceder a su modelo como cuando se ejecuta su aplicación.

Ejemplo

Una clase derivada de DbConfiguration podría tener este aspecto:

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

Esta clase configura EF para usar la estrategia de ejecución de SQL Azure —para reintentar automáticamente las operaciones de base de datos con errores— y usar la base de datos local para las bases de datos creadas por convención desde Code First.

Traslado de DbConfiguration

Hay casos en los que no es posible colocar la clase DbConfiguration en el mismo ensamblado que la clase DbContext. Por ejemplo, puede tener dos clases DbContext cada una en ensamblados diferentes. Hay dos opciones para gestionar esta situación.

La primera opción es usar el archivo de configuración para especificar la instancia de DbConfiguration que se va a usar. Para ello, establezca el atributo codeConfigurationType de la sección entityFramework. Por ejemplo:

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

El valor de codeConfigurationType debe ser el nombre completo del ensamblado y el espacio de nombres de la clase DbConfiguration.

La segunda opción es colocar DbConfigurationTypeAttribute en la clase de contexto. Por ejemplo:

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

El valor pasado al atributo puede ser su tipo DbConfiguration, como se muestra anteriormente, o la cadena de nombre completo del ensamblado y el espacio de nombres. Por ejemplo:

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

Configuración explícita de DbConfiguration

Hay algunas situaciones en las que puede ser necesaria la configuración antes de que se haya usado cualquier tipo DbContext. Algunos ejemplos de esto son:

  • Uso de DbModelBuilder para compilar un modelo sin contexto
  • Uso de cualquier otro código de marco o utilidad que use un DbContext donde se usa ese contexto antes de que el contexto de la aplicación

En tales situaciones, EF no puede detectar la configuración automáticamente y, en su lugar, debe realizar una de las siguientes acciones:

  • Establecer el tipo DbConfiguration en el archivo de configuración, tal como se describe en la sección Traslado de DbConfiguration anterior.
  • Llamar al método DbConfiguration.SetConfiguration estático durante el inicio de la aplicación

Invalidación de DbConfiguration

Hay algunas situaciones en las que es necesario invalidar el conjunto de configuración en DbConfiguration. Normalmente, esto no lo hacen los desarrolladores de aplicaciones, sino los proveedores y complementos de terceros que no pueden usar una clase de DbConfiguration derivada.

Para ello, EntityFramework permite registrar un controlador de eventos que pueda modificar la configuración existente justo antes de que se bloquee. También proporciona un método sencillo específicamente para reemplazar cualquier servicio devuelto por el localizador de servicios EF. Esta es la forma en que debe utilizarse:

  • En el inicio de la aplicación (antes de usar EF), el complemento o el proveedor deben registrar el método del controlador de eventos para este evento. (Tenga en cuenta que esto debe ocurrir antes de que la aplicación use EF).
  • El controlador de eventos hace una llamada a ReplaceService para cada servicio que deba reemplazarse.

Por ejemplo, para reemplazar IDbConnectionFactory y DbProviderService registraría un controlador similar al siguiente:

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

En el código anterior, MyProviderServices y MyConnectionFactory representan las implementaciones del servicio.

También puede agregar controladores de dependencia adicionales para obtener el mismo efecto.

Tenga en cuenta que también puede encapsular DbProviderFactory de esta manera, pero hacerlo solo afectará a EF y no a los usos del DbProviderFactory fuera de EF. Por este motivo, probablemente querrá seguir encapsulando DbProviderFactory como lo ha hecho antes.

También debe tener en cuenta los servicios que ejecuta externamente a su aplicación, por ejemplo, cuando ejecuta migraciones desde la consola del administrador de paquetes. Al ejecutar la migración desde la consola, intentará encontrar DbConfiguration. Sin embargo, la obtención del servicio encapsulado depende de dónde se registre el controlador de eventos. Si se registra como parte de la construcción de DbConfiguration, el código debe ejecutarse y el servicio debe encapsularse. Normalmente no será así y esto significa que las herramientas no recibirán el servicio encapsulado.