IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Entity Framework Discussion :

Code First : stratégie d'initialisation [Débutant]


Sujet :

Entity Framework

  1. #1
    Membre actif
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    315
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 315
    Points : 202
    Points
    202
    Par défaut Code First : stratégie d'initialisation
    Bonjour,

    je découvre ce concept avec enthousiasme : partir du code pour faire de la création de base via EF Code First.

    J'ai suivi ce tuto :

    Et il y a un concept que je ne saisis pas vraiment, lorsqu'on modifie nos DTO (rajout d'un champ ou d'une relation entre entités), suivant la stratégie d'initialisation de la base (ici) on peut
    définir plusieurs comportements.

    Mais sauf erreur de ma part, lorsqu'une modification doit être impactée (disons le rajout d'un champ supplémentaire) , on passe nécessairement par la destruction de la base avant sa recréation mais vide ?

    Certes il y a le concept de Seed pour réalimenter la nouvelle base, mais dans la vraie vie comment ça se passe si j'ai des milliers d'enregistrements à ré-injecter ?

    Merci de m'éclairer

  2. #2
    Membre habitué

    Inscrit en
    Février 2007
    Messages
    250
    Détails du profil
    Informations personnelles :
    Âge : 53

    Informations forums :
    Inscription : Février 2007
    Messages : 250
    Points : 162
    Points
    162
    Par défaut
    Non, il faut activer la migration sur ton projet :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Enable-Migrations -ProjectName "monprojetDAL" -StartUpProjectName "monprojet"
    Tout dépend de comment tu as architecturé ton projet.
    Personnellement j'ai une librairie DAL (Data Access Layer) et la migration est dedans puisque c'est elle qui s'occupe de l'accès à la données.

    Pour une base de données vide :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Add-Migration Version_1 -ProjectName "monprojetDAL" -StartUpProjectName "monprojet"
    Dans la classe configuration ajouter :
    AutomaticMigrationsEnabled = false;

    Ensuite il faut ouvrir la base et la migrer si elle existe ou la créer si elle n'existe pas.
    Je met le code brute :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
            static public void InitDatabaseModel(Type _typeDatabaseManagerContext)
            {
                // Analyse et migration de la base de données
                try
                {
                    //using(TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted }))
                    {   // Permet de faire un rollback si la création / Mise à jour de la BDD échoue
                        // Initialisation
                        Configuration configuration = new Configuration();
     
                        configuration.ContextType = _typeDatabaseManagerContext;
                        var migrator = new DbMigrator(configuration);
                        // This will update the schema of the DB
                        migrator.Update(); // This will run Seed() method
                        // scope.Complete(); //  Commiter
                    }
                }
                catch (AutomaticMigrationsDisabledException)
                {   // ici, pas besoin de lancer l'exception, la version de la base de données à changée
                }
                catch (Exception)
                {   // renvoyer l'exception plus haut
                    throw;
                }
     
                // Ne pas faire ce code dans le catch (AutomaticMigrationsDisabledException) car si une exception
                // est levée elle ne pourra plus être catchée et il faut le faire au cas où la migration a fonctionnée
                GeneralProvider provider = new GeneralProvider();
                EntityGeneral general = provider.GetGeneral();
     
                if (general == null)
                {   // Création de la base, ajouter le schéma actuel
                    WPFExtToolkit.Logger.Log.Info(String.Format("Initialisation de la version du schéma de la base de donnée : {0}", DatabaseManagerContext.DATABASE_SCHEMA_VERSION));
                    provider.Create(new EntityGeneral { SchemaVersion = DatabaseManagerContext.DATABASE_SCHEMA_VERSION });
     
                    // Créer la table des profiles
                    ProfileProvider.CreateProfiles();
     
                    // Création de la base : ajouter l'utilisateur Admin, asssocié au groupe admin
                    WPFExtToolkit.Logger.Log.Info("Création du compte administrateur");
                    EntityUtilisateur user = new EntityUtilisateur();
                    user.MotPasseClair = "monmotpasse";
                    user.Login = "Admin";
                    EntityProfile profileAdmin = new ProfileProvider().GetProfile(EntityProfile.Type.Administrateur);
                    user.ListProfiles.Add(profileAdmin);
                    UtilisateurProvider userProvider = new UtilisateurProvider();
                    userProvider.Create(user);  // Ajoute l'utilisateur et lui assigne le profile administrateur
                }
                else
                {   // La version de la BDD doit être <= à cette version de programme
                    if (general.SchemaVersion > DatabaseManagerContext.DATABASE_SCHEMA_VERSION)
                    {
                        throw new Exception("Le programme DataManager est incompatible avec version de la base de données\n\nVeuillez mettre à jour le programme.");
                    }
                    else if (general.SchemaVersion < DatabaseManagerContext.DATABASE_SCHEMA_VERSION)
                    {   // Mettre à jour le N° de version de la base de données en concordance avec la version du programme
                        // sachant que la migration a fonctionnée donc la version actuelle du schéma est egal à celui du
                        // programme
                        Log.Info(String.Format("Mise à jour de la version du schéma de la base de donnée : {0}", DatabaseManagerContext.DATABASE_SCHEMA_VERSION));
                        general.SchemaVersion = DatabaseManagerContext.DATABASE_SCHEMA_VERSION;
                        provider.Update(general);
                    }
                }
            }
    Je teste pas mal de choses : Si c'est une création de base (la table n'a pas de ligne, general == null) alors je crée l'utilisateur par défaut ainsi que la liste des différents profiles de l'application.
    Je met à jour la table générale avec la version du schéma de la base.
    Si c'est une mise à jour (version géneral < version du logiciel) je met à jour la table général avec le bon n° de version.
    Sinon, ça a fonctionné ? Alors si la version du logiciel est plus ancienne que la version de la base (Que fait EF ? Je ne sais pas encore) j'indique qu'il faut mettre à jour le programme car trop vieux et si la base a changée ça peut faire n'importe quoi !

    Voilà, je pense que ça peut être un bon début pour toi... C'est assez compliqué au début EF...

    Pour une base de données vide mais en cours de dev, il se peut qu'on la détruise, qu'on modifie la struture et qu'on veuille la re-créer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Add-Migration Version_1 -ProjectName "monprojetDAL" -StartUpProjectName "monprojet"
    Dans la classe configuration ajouter :
    Add-Migration Version_1 -ProjectName "monProjetDAL" -StartUpProjectName "monProjet" -force

    Une dernière chose : pour que le Add-Migration et tout le toutim fonctionne, il faut que le programme compile parce que c'est en le chargeant que le moteur de migration fonctionne.
    Or, personnellement, j'ai créé ma chaine de connexion à la main.
    Dans ma fonction de récupération de connexion, j'ai donc du code juste pour EF :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
            public static DbConnection                      Connection
            { 
                get
                {
                    if (m_InstanceDbConnection == null)
                    {
    #if DEBUG
                        Logger.InitLogger("Config\\log4net.config",typeof(DatabaseManagerContext));
     
                        Logger.Log.Info("-------------------------------------------------");
                        Logger.Log.Info("     Démarrage de Entity Framework Migration"     );
                        Logger.Log.Info("-------------------------------------------------");
     
                        // !! Attention : TRES IMPORTANT !!
                        // Pour faire fonctionner Entity Framework Migration, Le gestionnaire de package utilise le
                        // code source pour détecter les changements en base de données. Pour cela, il instancie la classe de
                        // contexte qui doit donc OBLIGATOIREMENT pouvoir se connecter lorsqu'elle est instancié sans aucune autre
                        // initialisation. Ce code ne sert donc qu'à celà et il doit contenir toute la chaine de connexion
                        // necessaire pour se connecter à la base de données de développement.
                        m_InstanceDbConnection = new OracleConnection("User Id=gdd; Password=gdd; Data Source=localhost:1521/orcl.168.255.133;Unicode=true;");
    #else
                        throw new Exception("Instance de connexion non initialisée !");
    #endif
                    }
                    return m_InstanceDbConnection;
                }
                set
                {
                    m_InstanceDbConnection = value;
                }
            }
    Bon, je m'arrête là, si tu as besoin de plus d'infos..

  3. #3
    Membre actif
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    315
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 315
    Points : 202
    Points
    202
    Par défaut
    Bonjour,

    merci de ta réponse très complète.

    Je suis débutant en C# et donc en Entity Framework, je vais prendre le temps de décortiquer ton code, toutes ces notions sont nouvelles pour moi.

    Pour le moment, je n'ai pas de projet, seulement de la lecture de tuto et de livres pour partir sur les meilleures pratiques possibles dans un projet d'initiation.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Entity Framework 4.1] Quelle est l'utilité du Code First ?
    Par Julien_G dans le forum Entity Framework
    Réponses: 3
    Dernier message: 19/08/2011, 09h25
  2. EF Code First et Read Only Property
    Par redkan dans le forum ASP.NET MVC
    Réponses: 2
    Dernier message: 29/06/2011, 14h22
  3. Réponses: 10
    Dernier message: 17/05/2011, 22h45
  4. [EF Code First] Relations entre tables
    Par john85 dans le forum ASP.NET MVC
    Réponses: 5
    Dernier message: 06/05/2011, 19h12
  5. Réponses: 1
    Dernier message: 04/12/2006, 07h55

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo