2014-10-14 13 views
11

Ieri ho eseguito la migrazione (EF 5.0 => EF 6.0) dell'applicazione Web che utilizza il framework entità per raggiungere database MySql e SQL Server (particolare DbContext a particolari database, NON uno qualsiasi DbContext per qualsiasi tipo di database).Stessa applicazione, diversi database: Entity framework 6.X + MySQL + SQL Server

cose fase di compilazione sono state fatte senza problemi, run-time mi ha affrontato con l'eccezione:

L'impostazione predefinita esempio DbConfiguration è stato utilizzato da Entity Framework prima del tipo 'MySqlEFConfiguration' stato scoperto.

L'attributo [DbConfigurationType(typeof(MySqlEFConfiguration))] sul contesto sembra essere stato ignorato in fase di esecuzione, perché il contesto è in un assembly esterno (?) E il DbConfiguration utilizzato invece è globale per il dominio di applicazione, non il specifica al contesto (?)."

ho provato diversi approcci per risolvere il problema, quindi su google e - sorpresa -. trovare alcuna soluzione di lavoro

Sembra situazione descritta ben formato qui http://forums.mysql.com/read.php?174,614148,614148 ancora non è cambiato, o perso alcune cose ovvie

Qualsiasi feedback sarà apprezzato.

Grazie in anticipo!

DESCRIZIONE DETTAGLIATA:

ingresso (semplificato): - ASP.NET Web Application layer di accesso

  • dati implementato su Entity Framework 6.1.1

  • Entity Fornitori di framework:

    • System.Data.SqlClient 6.1.1

    • MySql.Data.MySqlClient 6.9.4

  • MY_SqlContext, il modello primo concetto, mirato al mio database SQL Server

  • Ms_SqlContext, primo concetto del database, destinato al database MS SQL Server

Secondo la documentazione generica di Entity Framework 6 e MySQL Connector/Net documentazione (http://dev.mysql.com/doc/connector-net/en/connector-net-entityframework60.html), MY_SqlContext richiede MySqlEFConfiguration da applicare.

Secondo entrambe le documentazioni, di cui sopra, ci sono tre opzioni per farlo. Tutti e tre sono stati provati e falliti.

Opzione 1: Aggiunta del DbConfigurationTypeAttribute [DbConfigurationType(typeof(MySqlEFConfiguration))] alla classe MY_SqlContext

segmenti Web.config appropriati:

<connectionStrings> 
    <add name="MY_SqlContext" 
     connectionString="server=.;User Id=root;password=...;Persist Security Info=True;database=MySqlDb;Use Compression=False;Use Old Syntax=False" 
     providerName="MySql.Data.MySqlClient" /> 
    <add name="Ms_SqlContext" 
     connectionString="metadata=res://*/Ms_SqlContext.csdl|res://*/Ms_SqlContext.ssdl|res://*/Ms_SqlContext.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=.;initial catalog=MsSqlDb;User ID=appuser;Password=...&quot;" 
     providerName="System.Data.EntityClient" /> 
</connectionStrings> 

<entityFramework> 
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" /> 
    <providers> 
     <provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6" /> 
     <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /> 
    </providers> 
</entityFramework> 

Dopo l'avvio delle applicazioni e le richieste web iniziare l'elaborazione:

Ms_SqlContext funziona bene, ma cercando di creare un'istanza MY_SqlContext, ottengo l'eccezione:

L'istanza predefinita di DbConfiguration è stata utilizzata da Entity Framework prima che fosse scoperto il tipo "MySqlEFConfiguration". Un'istanza di "MySqlEFConfiguration" deve essere impostata all'avvio dell'applicazione prima di utilizzare qualsiasi funzionalità di Entity Framework o deve essere registrata nel file di configurazione dell'applicazione. Vedi ... LinkId = 260.883 per ulteriori informazioni "

Opzione 2:. Calling DbConfiguration.SetConfiguration (nuova MySqlEFConfiguration()) all'avvio dell'applicazione

segmenti Web.config appropriati (lo stesso di opzione 1, in realtà):

<connectionStrings> 
    <add name="MY_SqlContext" 
     connectionString="server=.;User Id=root;password=...;Persist Security Info=True;database=MySqlDb;Use Compression=False;Use Old Syntax=False" 
     providerName="MySql.Data.MySqlClient" /> 
    <add name="Ms_SqlContext" 
     connectionString="metadata=res://*/Ms_SqlContext.csdl|res://*/Ms_SqlContext.ssdl|res://*/Ms_SqlContext.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=.;initial catalog=MsSqlDb;User ID=appuser;Password=...&quot;" 
     providerName="System.Data.EntityClient" /> 
</connectionStrings> 

<entityFramework> 
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" /> 
    <providers> 
     <provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6" /> 
     <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /> 
    </providers> 
</entityFramework> 

codice, aggiunto al Global.asax.cs: private void Application_Start (object sender, EventArgs e) { DbConfiguratio n.SetConfiguration (new MySqlEFConfiguration()); ...

Dopo l'avvio delle applicazioni e le richieste web cominciano elaborazione cercando di creare un'istanza di Ms_SqlContext, ottengo l'eccezione:

Un'istanza di 'MySqlEFConfiguration' stato impostato ma questo tipo non è stato scoperto nel stesso assembly del contesto "Ms_SqlContext". Inserire il tipo DbConfiguration nello stesso assembly del tipo DbContext, utilizzare DbConfigurationTypeAttribute sul tipo DbContext per specificare il tipo DbConfiguration o impostare il tipo DbConfiguration nel file di configurazione. Vedi ...? LinkId = 260883 per ulteriori informazioni.

Opzione 3: Impostare il tipo DbConfiguration nel file di configurazione

segmenti Web.config appropriati

<connectionStrings> 
    <add name="MY_SqlContext" 
     connectionString="server=.;User Id=root;password=...;Persist Security Info=True;database=MySqlDb;Use Compression=False;Use Old Syntax=False" 
     providerName="MySql.Data.MySqlClient" /> 
    <add name="Ms_SqlContext" 
     connectionString="metadata=res://*/Ms_SqlContext.csdl|res://*/Ms_SqlContext.ssdl|res://*/Ms_SqlContext.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=.;initial catalog=MsSqlDb;User ID=appuser;Password=...&quot;" 
     providerName="System.Data.EntityClient" /> 
</connectionStrings> 

<entityFramework codeConfigurationType="MySql.Data.Entity.MySqlEFConfiguration, MySql.Data.Entity.EF6"> 
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" /> 
    <providers> 
     <provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6" /> 
     <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /> 
    </providers> 
</entityFramework> 

Dopo l'avvio delle applicazioni e le richieste web iniziare l'elaborazione: ... Ms_SqlContext l'istanza viene creata, ma durante l'esecuzione della prima query, ottengo l'eccezione:

EntityException: { "Il provider sottostante fallito su Apri."}

InnerException: { "Impossibile connettersi a qualsiasi degli host MySQL specificate"}

Quindi, Ms_SqlContext ottenere configurazione di MySQL che è ovviamente sbagliato.

+0

opzione 3 fissata per me, thx – wodzu

risposta

3

È corretto che esiste solo un DbConfiguration per AppDomain anziché uno per contesto. Ci sono ulteriori informazioni su come specificarlo qui - http://msdn.microsoft.com/en-us/data/jj680699#Moving. Se si dispone di più configurazioni e si desidera essere sicuri di aver caricato quello corretto, è probabile che si desideri l'opzione del file di configurazione del metodo statico DbConfiguration.SetConfiguration.

Sembra che MySQL stia sostituendo una serie di servizi nel risolutore di dipendenze, ma le implementazioni che stanno registrando funzionano solo per MySQL.

La configurazione basata su codice è davvero progettata per gli sviluppatori finali per configurare la propria configurazione piuttosto che per i singoli fornitori per la spedizione di uno preconfigurato (poiché ce n'è uno solo per AppDomain).

La mia raccomandazione è di non usare la loro, di crearne di propri e di registrare solo i servizi che è necessario/desiderato. Per esempio la loro strategia di esecuzione sarebbe una buona cosa per la registrazione - e la registrazione è provider specifico:

SetExecutionStrategy(MySqlProviderInvariantName.ProviderName,() => new MySqlExecutionStrategy());

Ci sarà probabilmente un po 'di pista ed errore, come si lavora esattamente ciò che deve essere registrato al fine per il loro fornitore a lavorare.

+0

Ciao, Rowan.In realtà, non sono ossessionato dall'idea di ottenere un DbConfiguration per su Tipo di contesto. Voglio far funzionare due diversi tipi (MsSql e MySql) dbcontexts in un'unica applicazione. Il contesto MySql richiedeva l'utilizzo del tipo MySqlEFConfiguration - tramite configurazione o DbConfiguration.SetConfiguration o con attributo DbConfigurationType. Se configuro MySql, i contesti MySql funzionano correttamente, ma i contesti MsSql non riescono, perché ottengono la stessa configurazione (errata per loro). Non capisco completamente come farli funzionare entrambi nella stessa app –

+0

Puoi farmi sapere quale errore stai vedendo, dovresti essere in grado di avere config per più provider nella stessa configurazione. –

+0

Ciao, Rowan. Grazie per il tuo contributo. Si prega di trovare la descrizione degli errori più dettagliati nel post della domanda, al di sotto del blocco DESCRIZIONE DETTAGLIATA: –

1

È possibile utilizzare il costruttore di contesto che accetta un collegamento DB e fornisce la connessione corretta al contesto.

Per un esempio vedere questa domanda: EF6 and multiple configurations (SQL Server and SQL Server Compact)

+0

Sì, ho visto quel post. Il problema è che usiamo DbContextPooler personalizzato, che funziona con un altro sovraccarico del costruttore e stringhe di connessione già preparate. Inoltre ho giocato (brevemente, non spendere molto tempo) con questo tipo di esempio - ottenere alcuni errori durante la creazione di Sql Connection –

+0

Questa risposta IMHO è facilmente trascurata. Infatti, quale costruttore di DbContext è stato utilizzato ha influenzato molto la DbConfiguration utilizzata. – BozoJoe

6

Quindi, la soluzione finale è:

  1. Creare proprio successore DbConfiguration con il blackjack e prostitute:

    public class MultipleDbConfiguration : DbConfiguration 
        { 
         #region Constructors 
    
         public MultipleDbConfiguration() 
         { 
          SetProviderServices(MySqlProviderInvariantName.ProviderName, new MySqlProviderServices()); 
         } 
    
         #endregion Constructors 
    
         #region Public methods 
    
         public static DbConnection GetMySqlConnection(string connectionString) 
         { 
          var connectionFactory = new MySqlConnectionFactory(); 
    
          return connectionFactory.CreateConnection(connectionString); 
         } 
    
         #endregion Public methods 
        } 
    
  2. Mark Ms_SqlContext con MultipleDbConfiguration (e non fare nient'altro con quel tipo di DbContext)

    [DbConfigurationType(typeof(MultipleDbConfiguration))] 
        partial class Ms_SqlContext 
        { 
        } 
    
  3. Mark Ms_SqlContext con MultipleDbConfiguration, e MY_SqlContext ajust (nameOrConnectionString stringa) con la chiamata MultipleDbConfiguration.GetMySqlConnection (nameOrConnectionString)

    [DbConfigurationType(typeof(MultipleDbConfiguration))] 
        partial class MY_SqlContext : DbContext 
        { 
           public MY_SqlContext(string nameOrConnectionString) : base(MultipleDbConfiguration.GetMySqlConnection(nameOrConnectionString), true) 
           {} 
        } 
    
  4. CHE SIA !!!

+0

Ho avuto un bel po 'di problemi quando uso # 3 - il costruttore che utilizza solo una stringa. La risposta su http://stackoverflow.com/a/26422427/38461 ha dato risultati molto più consistenti. – BozoJoe

4

FYIW - Ho avuto lo stesso problema. L'unica cosa che risolveva il problema era aggiungere il seguente codice all'inizio dell'esecuzione del mio programma.

var needsToBeInstantiated = new EFDBContextConfiguration(); 
EFDBContextConfiguration.SetConfiguration(needsToBeInstantiated); 
+0

Correggo la risposta. 'EFDBContextConfiguration' dovrebbe essere sostituito con la propria classe' XConfiguration' che eredita 'DbConfiguration'. –

+0

E se volessimo chiamare queste due linee da qualche parte nel programma ?, –

+0

potrebbe essere semplicemente 'DbConfiguration.SetConfiguration (new YourDbConfigurationClass());' – thepirat000

1

ho avuto lo stesso errore, e nel mio caso ho avuto una classe DbConfiguration definito in un altro assembly. Anche se si trovava nella stessa dll dello DbContext, penso che venga catturato solo in fase di esecuzione a causa del caricamento o del riflesso lazy o qualcosa del genere.

Il modo migliore che ho trovato è stato quello di metterlo in web.config o app.config utilizzando l'attributo codeConfigurationType sul nodo entityFramework come descritto here.

Problemi correlati