2011-11-07 2 views
5

J'ai une base de données SqlServer Compact Edition qui contient 2 tables.Puis-je avoir deux contextes EntityFramework différents partageant une seule base de données SqlServer Compact?

Pour chacune de ces tables, j'ai une classe de contexte dérivée de DbContext qui est utilisée par l'application pour accéder à la table.

Afin de garder les différents composants de l'application découplés, je ne peux pas avoir une classe de contexte qui aurait des propriétés DbSet pour les deux tables. Au contraire, j'ai besoin d'avoir 2 classes de contexte différentes, chacune d'entre elles doit être complètement inconsciente de l'autre et de ses données. J'utilise l'approche code-first, mon code définit les entités et le modèle, et je laisse Entity Framework créer la base de données pour moi.

Mon problème est: comment puis-je laisser Entity Framework créer automatiquement la base de données et les tables lors de l'initialisation du contexte, mais les 2 contextes partagent-ils toujours la même base de données et la même connexion?

En ce moment ce que je reçois est, le premier contexte crée avec succès la base de données et la table, mais lorsque je tente de créer le deuxième contexte, j'obtiens, sans surprise l'erreur suivante:

The model backing the 'SomeObjectContext' context has changed since the database 
was created. Either manually delete/update the database, or call Database.SetInitializer 
with an IDatabaseInitializer instance. For example, the DropCreateDatabaseIfModelChanges 
strategy will automatically delete and recreate the database, and optionally seed it with 
new data. 

Aucun des IDatabaseInitializer disponibles ne me convient, car je ne veux pas que la base de données entière soit supprimée lorsque le second contexte est créé. Je veux juste que la table du second contexte soit créée dans la base de données existante.

Tout conseil sur la façon de résoudre ce problème serait apprécié.

Merci

Répondre

5

Vous ne pouvez pas utiliser CodeFirst cette façon avec une seule base de données. CodeFirst doit vérifier les classes du modèle par rapport à la structure db pour fonctionner correctement (elles doivent être "synchronisées").

In order to keep the different components of the application decoupled, I can't have one context class that would have DbSet properties for both of the tables. Rather, I need to have 2 different context class, each of them has to be completely unaware of the other and its data.

Si des tables d'exposition ont aucun lien entre eux et son exigence pour votre application d'avoir ces tableaux complètement séparés, pourquoi ne pas créer deux bases de données et un contexte pour chacun d'eux?

En tout, je voudrais aller avec une base de données, avoir un interne DbContext et deux classes différentes de référentiel public qui encapsulent l'accès aux deux tables. Si tout votre code se trouve dans le même assembly, vous pouvez accéder à votre contexte interne à partir de votre classe de référentiel. Quelqu'un qui a besoin d'accéder au référentiel peut accéder au référentiel pour la table dont il a besoin.

+2

Il obtient un problème dans un environnement comme Sql Azure où vous êtes facturé par base de données ... – Clement

2

Oui, vous pouvez utiliser plusieurs contextes de base de données pointant vers la même base de données.

Arthur Vickers de l'équipe Entity Framework recommande le modèle suivant .... Au lieu de spécifier des chaînes de connexion distinctes dans votre fichier app.config pour plusieurs contextes, définissez simplement une chaîne et donnez-lui un nom générique.

<connectionStrings> 
     <add name="MyDBContext" connectionString="Your conn string here" providerName="System.Data.SqlClient" /> 
    </connectionStrings> 

Ensuite, créez une classe de contexte de base qui utilisera la chaîne de connexion:

using System.Data.Entity; 

namespace DataLayer 
{ 
    public class BaseContext<TContext> : DbContext where TContext : DbContext 
    { 
     static BaseContext() 
     { 
      Database.SetInitializer<TContext>(null); 
     } 
     protected BaseContext() 
      : base("name=MyDBContext") 
     { 
     } 

    } 
} 

Maintenant, héritent ce comportement de base dans chaque contexte (par exemple):

namespace DataLayer.Models 

    { 
     public class OrderContext : BaseContext<OrderContext> 

    … 

    namespace DataLayer.Models 
    { 
     public class ProductContext : BaseContext<ProductContext> 
    … 
+0

Merci d'avoir répondu. Ma question portait spécifiquement sur une base de données SqlServer CE, et je pense que l'approche que vous décrivez dans la réponse ne résout pas le problème que j'avais. Le problème était spécifiquement avec la façon dont le code fonctionnait en premier et CE fonctionnait. – Ran

+0

Désolé Ran. Peut avoir mal compris votre question .... – tom33pr

Questions connexes