web-dev-qa-db-fra.com

EF6 et configurations multiples (SQL Server et SQL Server Compact)

Mise à jour: Problème résolu, voir fin de cette question.

Le problème:

Nous essayons d'utiliser Entity Framework 6 et une configuration basée sur du code dans un scénario où nous avons utilisé à la fois SQL Server et SQL Server CE dans la même AppDomain.

Ce scénario assez simple ne semble pas être pris en charge "de par sa conception". De l'équipe EF:

Remarque: nous ne prenons pas en charge l'utilisation de plusieurs classes de configuration dans le même AppDomain. Si vous utilisez cet attribut pour définir différent classes de configuration pour deux contextes, une exception sera levée.

Plus d'informations ici: Configuration basée sur code (Codeplex)

La question:

Comment pouvons-nous avancer à partir d'ici? Toute aide serait grandement appréciée! Existe-t-il un moyen plus flexible de connecter une configuration à un contexte plutôt qu’à une AppDomain?

(Nos classes de contexte sont situées dans différents assemblys. Nous avons essayé l'attribut DbConfigurationType mais le problème est EF lui-même)

Fichiers de configuration:

Configuration pour serveur SQL normal

public class EfConfiguration : DbConfiguration
{
    public EfConfiguration()
    {
        SetProviderServices(
            SqlProviderServices.ProviderInvariantName, 
            SqlProviderServices.Instance);

        SetDefaultConnectionFactory(new SqlConnectionFactory());
    }
}

Configuration pour SQL Server Compact Edition

public class EfCeConfiguration : DbConfiguration
{
    public EfCeConfiguration()
    {
        SetProviderServices(
            SqlCeProviderServices.ProviderInvariantName,
            SqlCeProviderServices.Instance);

        SetDefaultConnectionFactory(
            new SqlCeConnectionFactory(SqlCeProviderServices.ProviderInvariantName));
    }
}

METTRE À JOUR:

L'erreur que nous obtenons est:

System.TypeInitializationException: l'initialiseur de type pour 'MyProject.Repositories.Base.DataContext' jeté une exception. ----> System.InvalidOperationException: Un instance de 'EfCeConfiguration' a été définie mais ce type n'était pas découvert dans le même assemblage que le contexte 'DataContext'. Non plus placez le type DbConfiguration dans le même assemblage que DbContext type, utilisez DbConfigurationTypeAttribute sur le type DbContext à spécifiez le type DbConfiguration ou définissez le type DbConfiguration dans le fichier de configuration. Voir http://go.Microsoft.com/fwlink/?LinkId=260883 pour Plus d'information.

UPDATE 2, la solution Comme décrit ci-dessus, nous ne pouvons avoir qu'une seule configuration. C'est un problème car Sql et SqlCe utilisent des fournisseurs différents. Si nous utilisons "SetDefaultConnectionFactory" pour s’adapter à un type de base de données, l’autre échouera.

Au lieu de cela, fournissez la connexion dans le contexte comme décrit dans l'article marqué comme réponse ci-dessous. Une fois que vous initialisez toujours le contexte avec une connexion plutôt qu'une chaîne de connexion, vous êtes prêt à partir. Vous pouvez supprimer l'appel SetDefaultConnectionFactory de la configuration. Nous utilisons uniquement le code ci-dessous pour configurer le contexte SqlCe et aucune configuration pour le contexte Sql.

  public class CommonEfConfiguration : DbConfiguration
    {
        public CommonEfConfiguration()
        {
            // EF does not know if the ce provider by default,
            // therefore it is required to be informed about it.
            // The connection factories are not necessary since the connection
            // is always created in the UnitOfWork classes
            SetProviderServices(SqlCeProviderServices.ProviderInvariantName, SqlCeProviderServices.Instance);
        }
    }
20
Henrik Carlsson

EDIT: basé sur les détails de l'erreur: .__ Avez-vous déjà essayé d'indiquer à EF où se trouve la classe de configuration?

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

Si cela ne peut pas être fait le travail, alors voir une alternative

Utiliser le contexte avec le constructeur DbConnection 

public class MYDbContext : DbContext {
     // MIgration parameterless constructor is managed in  MyMigrationsContextFactory 

    public MyDbContext(string connectionName) : base(connectionName) { } // no this

    public MYDbContext(DbConnection dbConnection, bool contextOwnsConnection)  // THIS ONE
        : base(dbConnection, contextOwnsConnection) {  }

vous avez ensuite besoin d’une connexion "DBConnection" pour chaque fournisseur . Pour SQL Server

      public DbConnection GetSqlConn4DbName(string dataSource, string dbName) {
        var sqlConnStringBuilder = new SqlConnectionStringBuilder();
        sqlConnStringBuilder.DataSource = String.IsNullOrEmpty(dataSource) ? DefaultDataSource : dataSource;
        sqlConnStringBuilder.IntegratedSecurity = true;
        sqlConnStringBuilder.MultipleActiveResultSets = true;

        var sqlConnFact = new SqlConnectionFactory(sqlConnStringBuilder.ConnectionString);
        var sqlConn = sqlConnFact.CreateConnection(dbName);
        return sqlConn;
    }

répéter pour l’usine SqlCe, il peut également générer une connexion DBC Le facteur de connexion SqlCe crée une connexion

12
phil soady

ce que j'ai fait:

public partial class MyDataBaseContext : DbContext
{
    public MyDataBaseContext (string ConnectionString)
        : base(ConnectionString)
    {
    }
}
2
havalli

J'ai trouvé la solution dans un post sur un post de forum Microsoft .

En gros, j'ai eu deux projets, chacun avec son propre contexte. Entity Framework chargeait seulement (la première) l'une des classes de DbConfiguration et essayait d'utiliser cette même configuration pour les deux projets. C'est la raison du message d'erreur disant quelque chose comme 

"Une instance de 'EfCeConfiguration' a été définie mais ce type n'a pas été découvert dans le même assembly que le contexte 'DataContext'".

Ainsi, comme quelqu'un l'a suggéré dans que le forum Microsoft , j'ai supprimé toutes les annotations [DbConfigurationType(typeof(DbConfigurationClass))] des classes qui héritent de DbContext dans les deux projets, et l'erreur ne s'est plus produite.

0
Ulysses Alves