Configurazione basata su codice

Nota

Solo EF6 e versioni successive: funzionalità, API e altri argomenti discussi in questa pagina sono stati introdotti in Entity Framework 6. Se si usa una versione precedente, le informazioni qui riportate, o parte di esse, non sono applicabili.

La configurazione per un'applicazione Entity Framework può essere specificata in un file di configurazione (app.config/web.config) o tramite codice. Quest'ultimo è noto come configurazione basata su codice.

La configurazione in un file di configurazione è descritta in un articolo separato. Il file di configurazione ha la precedenza sulla configurazione basata su codice. In altre parole, se un'opzione di configurazione è impostata sia nel codice che nel file di configurazione, viene usata l'impostazione nel file di configurazione.

uso di DbConfiguration

La configurazione basata su codice in EF6 e versioni successive viene ottenuta creando una sottoclasse di System.Data.Entity.Config.DbConfiguration. Quando si sottoclassa DbConfigurationè necessario seguire le linee guida seguenti:

  • Creare una DbConfiguration sola classe per l'applicazione. Questa classe specifica le impostazioni a livello di dominio app.
  • Posizionare la DbConfiguration classe nello stesso assembly della DbContext classe. (Vedere il Se DbConfiguration si desidera modificare questa sezione, spostare questa sezione.
  • Assegnare alla DbConfiguration classe un costruttore pubblico senza parametri.
  • Impostare le opzioni di configurazione chiamando i metodi protetti DbConfiguration dall'interno di questo costruttore.

Seguendo queste linee guida, Entity Framework può individuare e usare automaticamente la configurazione tramite strumenti che devono accedere al modello e quando viene eseguita l'applicazione.

Esempio

Una classe derivata da DbConfiguration potrebbe essere simile alla seguente:

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

Questa classe configura Entity Framework per l'uso della strategia di esecuzione di SQL Azure, per ripetere automaticamente le operazioni di database non riuscite e per usare il database locale per i database creati per convenzione da Code First.

Spostarsi DbConfiguration

In alcuni casi non è possibile inserire la DbConfiguration classe nello stesso assembly della DbContext classe. Ad esempio, è possibile avere due DbContext classi ognuna in assembly diversi. Sono disponibili due opzioni per la gestione di questa operazione.

La prima opzione consiste nell'usare il file di configurazione per specificare l'istanza DbConfiguration da usare. A tale scopo, impostare l'attributo codeConfigurationType della sezione entityFramework. Ad esempio:

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

Il valore di codeConfigurationType deve essere il nome completo dell'assembly e dello spazio dei nomi della DbConfiguration classe.

La seconda opzione consiste nell'inserire DbConfigurationTypeAttribute nella classe di contesto. Ad esempio:

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

Il valore passato all'attributo può essere il DbConfiguration tipo , come illustrato in precedenza, oppure l'assembly e la stringa del nome del tipo qualificato dello spazio dei nomi. Ad esempio:

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

Impostazione DbConfiguration esplicita

In alcune situazioni potrebbe essere necessaria la configurazione prima dell'uso di qualsiasi DbContext tipo. Di seguito sono riportati alcuni esempi:

  • Uso DbModelBuilder di per compilare un modello senza contesto
  • Uso di un altro codice framework/utilità che usa un DbContext oggetto in cui viene usato tale contesto prima che venga usato il contesto dell'applicazione

In tali situazioni Ef non è in grado di individuare automaticamente la configurazione ed è necessario eseguire una delle operazioni seguenti:

  • Impostare il DbConfiguration tipo nel file di configurazione, come descritto nella sezione Spostamento DbConfiguration precedente
  • Chiamare l'oggetto statico DbConfiguration. Metodo SetConfiguration durante l'avvio dell'applicazione

Override DbConfiguration

In alcune situazioni è necessario eseguire l'override del set di configurazione in DbConfiguration. Questa operazione non viene in genere eseguita dagli sviluppatori di applicazioni, ma piuttosto da provider e plug-in di terze parti che non possono usare una classe derivata DbConfiguration .

Per questo motivo, EntityFramework consente la registrazione di un gestore eventi che può modificare la configurazione esistente subito prima che venga bloccata. Fornisce inoltre un metodo di zucchero specifico per sostituire qualsiasi servizio restituito dal localizzatore di servizi EF. Questo è il modo in cui deve essere usato:

  • All'avvio dell'app (prima dell'uso di ENTITY) il plug-in o il provider deve registrare il metodo del gestore eventi per questo evento. Si noti che questa operazione deve verificarsi prima che l'applicazione usi Entity Framework.
  • Il gestore eventi effettua una chiamata a ReplaceService per ogni servizio che deve essere sostituito.

Ad esempio, per sostituire IDbConnectionFactory e DbProviderService registrare un gestore simile al seguente:

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

Nel codice precedente MyProviderServices e MyConnectionFactory rappresentano le implementazioni del servizio.

È anche possibile aggiungere gestori di dipendenze aggiuntivi per ottenere lo stesso effetto.

Si noti che è anche possibile eseguire il wrapping DbProviderFactory in questo modo, ma questa operazione influirà solo su Entity Framework e non sugli usi dell'esterno DbProviderFactory di Entity Framework. Per questo motivo è probabile che si voglia continuare a eseguire il wrapping DbProviderFactory come in precedenza.

Tenere presente anche i servizi eseguiti esternamente all'applicazione, ad esempio quando si eseguono migrazioni dalla console di Gestione pacchetti. Quando si esegue la migrazione dalla console, tenterà di trovare l'oggetto DbConfiguration. Tuttavia, se otterrà o meno il servizio di cui è stato eseguito il wrapping dipende dalla posizione in cui è stata registrata dal gestore eventi. Se è registrato come parte della costruzione del codice DbConfiguration , il codice deve essere eseguito e il servizio deve essere sottoposto a wrapping. In genere questo non sarà il caso e questo significa che gli strumenti non otterranno il servizio di cui è stato eseguito il wrapping.