2014-10-14 1 views
11

Gestern habe ich Migration (EF 5.0 => EF 6.0) der Webanwendung, die Entity Framework verwendet, um MySql und SQL Server-Datenbanken zu erreichen (insbesondere DbContext zu bestimmten Datenbanken, keine DbContext zu jeder Art von Datenbank).Gleiche Anwendung, verschiedene Datenbanken: Entity Framework 6.X + MySQL + SQL Server

Compile Zeit, die Dinge wurden ohne Probleme getan, Laufzeit konfrontiert mich mit Ausnahme:

Der Standard DbConfiguration Instanz durch das Entity Framework vor der ‚MySqlEFConfiguration‘ Typ entdeckt wurde verwendet.

Das [DbConfigurationType(typeof(MySqlEFConfiguration))] Attribut im Kontext erscheint zur Laufzeit ignoriert worden zu sein, weil der Kontext in einer externen Baugruppe ist (?) Und die DbConfiguration verwendete stattdessen auf die Anwendungsdomäne global, nicht die spezifisch für den Kontext (?).“

ich habe versucht, verschiedene Ansätze, es zu beheben, gegoogelt es dann und - Überraschung -. keine funktionierende Lösung finden

Sieht aus wie beschrieben Situation hier gut ausgebildet http://forums.mysql.com/read.php?174,614148,614148 noch nicht geändert, oder vermisste ich einige offensichtliche Dinge

Jede Rückmeldung wird geschätzt.

Vielen Dank im Voraus!

AUSFÜHRLICHE BESCHREIBUNG:

Input (vereinfacht): - ASP.NET Web Application

  • Zugriffsdatenschicht über Entity Framework implementiert 6.1.1

  • Entity Framework-Anbieter:

    • System.Data.SqlClient 6.1.1

    • MySql.Data.MySqlClient 6.9.4

  • MY_SqlContext, Modell erstes Konzept, gezielt zu MY SQL Server-Datenbank

  • Ms_SqlContext, erstes Konzept der Datenbank, Ziel der MS SQL Server-Datenbank

Entsprechend der allgemeinen Dokumentation von Entity Framework 6 und der MySql Connector/Net-Dokumentation (http://dev.mysql.com/doc/connector-net/en/connector-net-entityframework60.html), MY_SqlContext erfordert, dass MySqleEFConfiguration angewendet wird.

Gemäß den beiden obigen Dokumentationen gibt es drei Möglichkeiten, dies zu tun. Alle drei wurden versucht und versagt.

Option 1: Hinzufügen des DbConfigurationTypeAttribute [DbConfigurationType(typeof(MySqlEFConfiguration))] zu MY_SqlContext Klasse

Geeignete Web.config Segmente:

<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> 

Nach Anwendung gestartet und Web-Anfragen beginnen Verarbeitung:

Ms_SqlContext funktioniert gut, aber Beim Versuch, eine MY_SqlContext-Instanz zu erstellen, erhalte ich die Ausnahme:

Die standardmäßige DbConfiguration-Instanz wurde vom Entity Framework verwendet, bevor der Typ 'MySqlEFConfiguration' erkannt wurde. Eine Instanz von 'MySqlEFConfiguration' muss beim Anwendungsstart festgelegt werden, bevor Entity Framework-Features verwendet werden oder in der Konfigurationsdatei der Anwendung registriert werden muss. Siehe ... LinkId = 260.883 für weitere Informationen „

Option 2. Der Aufruf DbConfiguration.SetConfiguration (neu MySqlEFConfiguration()) am Start der Anwendung

Geeignete Web.config Segmente (wie bei Option 1, tatsächlich):

<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> 

Code hinzugefügt Global.asax.cs: private void Application_Start (object sender, EventArgs e) { DbConfiguratio n.SetConfiguration (neu MySqleEFConfiguration()); ...

Nach Anwendung gestartet und Web-Anfragen beginnen Verarbeitung eine Ms_SqlContext Instanz zu erstellen versuchen, erhalte ich die Ausnahme:

Eine Instanz von ‚MySqlEFConfiguration‘ gesetzt wurde, aber diese Art in der nicht entdeckt wurde selbe Assembly wie der 'Ms_SqlContext' Kontext. Setzen Sie den DbConfiguration-Typ in derselben Assembly wie den DbContext-Typ, verwenden Sie DbConfigurationTypeAttribute für den DbContext-Typ, um den DbConfiguration-Typ anzugeben, oder legen Sie den DbConfiguration-Typ in der Konfigurationsdatei fest. Siehe ...? LinkId = 260883 für weitere Informationen.

Option 3: Stellen Sie den DbConfiguration Typ in der Konfigurationsdatei beginnen

Geeignete Web.config Segmente

<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> 

Nach Anwendung gestartet und Web-Anfragen Verarbeitung: ... Ms_SqlContext Instanz wird erstellt, aber während der ersten Abfrageausführung erhalte ich die Ausnahme:

EntityException: { "Der zugrunde liegende Anbieter schlug fehl auf Öffnen."}

Innerexception: { "Kann nicht eine der angegebenen MySQL Hosts verbinden"}

So Ms_SqlContext erhalten MySql Konfiguration, ist offensichtlich falsch.

+0

Option 3 es – wodzu

Antwort

3

Sie haben Recht, dass pro AppDomain nur eine DbConfiguration vorhanden ist und keine pro Kontext. Es gibt weitere Informationen, wie Sie es hier angeben können - http://msdn.microsoft.com/en-us/data/jj680699#Moving. Wenn Sie mehrere Konfigurationen haben und sicher sein wollen, dass die richtige Version geladen ist, sollten Sie wahrscheinlich die Konfigurationsdateioption der statischen DbConfiguration.SetConfiguration-Methode verwenden.

Es sieht so aus, als ob MySQL eine Reihe von Diensten im Dependency Resolver ersetzt, aber die Implementierungen, die sie registrieren, funktionieren nur für MySQL.

Code-basierte Konfiguration ist wirklich für End-Entwickler zum Einrichten ihrer Config eher als für einzelne Anbieter, um eine vorgebackene zu versenden (da es nur eine pro AppDomain gibt) konzipiert.

Meine Empfehlung ist es, ihre nicht zu verwenden, erstellen Sie eigene und registrieren nur Dienste, die Sie benötigen/wollen. Zum Beispiel würde ihre Ausführungsstrategie eine gute Sache zu registrieren sein - und die Registrierung ist Anbieter spezifisch:

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

Es gibt wohl ein bisschen Pfad und Fehler werden sein, wie Sie genau herausfinden, was um registriert werden muss für ihren Anbieter zu arbeiten.

+0

für mich, thx fixiert set Hallo, Rowan.Eigentlich bin ich nicht besessen davon, eine DbConfiguration per Context-Typ zu bekommen. Ich möchte arbeiten zwei verschiedene Arten (MsSQL und MySql) dbcontexts in einer Anwendung. MySql-Kontext erfordert die Verwendung von MySqlEFConfiguration-Typ - durch Konfiguration oder durch DbConfiguration.SetConfiguration oder mit DbConfigurationType-Attribut. Wenn ich MySql gut konfiguriere MySql-Kontexte funktioniert ok, aber MsSql Kontexte schlägt fehl, weil sie die gleiche (für sie falsch) Konfiguration erhalten. Ich verstehe komplett nicht, wie sie beide funktionieren in der gleichen App –

+0

Können Sie mir wissen, welchen Fehler Sie sehen, sollten Sie in der Lage sein, für mehrere Anbieter in der gleichen Konfiguration zu konfigurieren. –

+0

Hallo, Rowan. Danke für deinen Beitrag. Bitte finden Sie detaillierte Fehler Beschreibung in der Frage post, unten DETAILLIERTE BESCHREIBUNG Block: –

1

Sie können den Context-Konstruktor verwenden, der eine DBConnection übernimmt und die korrekte Verbindung zum Kontext bereitstellt.

Ein Beispiel dieser Frage sehen: EF6 and multiple configurations (SQL Server and SQL Server Compact)

+0

Ja, ich habe diesen Beitrag gesehen. Das Problem besteht darin, dass wir den benutzerdefinierten DbContextPooler verwenden, der mit einer anderen Konstruktorüberladung und bereits vorbereiteten Verbindungszeichenfolgen arbeitet. Auch ich spielte (kurz, nicht viel Zeit) mit einer Art von diesem Beispiel - einige Fehler während der Sql Connection Erstellung –

+0

bekommen Diese Antwort ist IMHO leicht übersehen. In der Tat hat der verwendete DbContext-Konstruktor die verwendete DbConfiguration stark beeinflusst. – BozoJoe

6

So Endlösung ist:

  1. eigene erstellen DbConfiguration Nachfolger mit Blackjack und Nutten:

    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 mit MultipleDbConfiguration (und nichts anderes mit dieser Art von DbContext)

    [DbConfigurationType(typeof(MultipleDbConfiguration))] 
        partial class Ms_SqlContext 
        { 
        } 
    
  3. Mark Ms_SqlContext mit MultipleDbConfiguration und ajust MY_SqlContext (string nameOrConnectionString) mit Aufruf MultipleDbConfiguration.GetMySqlConnection (nameOrConnectionString)

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

+0

Ich hatte einige Probleme bei der Verwendung von # 3 - der Konstruktor nur mit einer Zeichenfolge. Die Antwort unter http://stackoverflow.com/a/26422427/38461 ergab wesentlich konsistentere Ergebnisse. – BozoJoe

4

FYIW - Ich hatte das gleiche Problem. Das einzige Problem, das das Problem gelöst hat, war, den folgenden Code am Anfang der Ausführung meines Programms hinzuzufügen.

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

Ich korrigiere die Antwort. 'EFDBContextConfiguration' sollte durch Ihre eigene' XConfiguration' Klasse ersetzt werden, die 'DbConfiguration' erbt. –

+0

Was, wenn wir diese zwei Zeilen irgendwo Mitte im Programm aufrufen möchten, –

+0

könnte es einfach 'DbConfiguration.SetConfiguration (new YourDbConfigurationClass());' sein – thepirat000

1

Ich hatte den gleichen Fehler, und in meinem Fall hatte ich eine DbConfiguration Klasse in einer anderen Baugruppe definiert. Obwohl es in der gleichen DLL war wie die DbContext, ich denke, es fängt nur zur Laufzeit wegen der Lazy Loading oder Reflexion oder so etwas.

Der beste Weg, die ich gefunden habe war es in web.config oder app.config mit dem codeConfigurationType Attribut auf dem entityFramework Knoten wie here.

Verwandte Themen