diff --git a/Exemples.sln b/Exemples.sln index 3f605ba..d9a49e8 100644 --- a/Exemples.sln +++ b/Exemples.sln @@ -566,6 +566,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ex_042_006_Keys_FluentAPI", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ex_042_007_ValueGeneration", "p08_BDD_EntityFramework\ex_042_007_ValueGeneration\ex_042_007_ValueGeneration.csproj", "{DA7ADAF3-34FF-4B97-8306-EF490A7A713A}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "03. Initialization Strategy and Seeding Data with CodeFirst", "03. Initialization Strategy and Seeding Data with CodeFirst", "{78374D80-5BE7-425D-BE62-AD8F26491112}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ex_042_008_InitializationStrategy", "p08_BDD_EntityFramework\ex_042_008_InitializationStrategy\ex_042_008_InitializationStrategy.csproj", "{3C9128AD-B677-460B-A1E1-D5B8B1491157}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -4702,6 +4706,26 @@ Global {DA7ADAF3-34FF-4B97-8306-EF490A7A713A}.Release|x64.Build.0 = Release|Any CPU {DA7ADAF3-34FF-4B97-8306-EF490A7A713A}.Release|x86.ActiveCfg = Release|Any CPU {DA7ADAF3-34FF-4B97-8306-EF490A7A713A}.Release|x86.Build.0 = Release|Any CPU + {3C9128AD-B677-460B-A1E1-D5B8B1491157}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3C9128AD-B677-460B-A1E1-D5B8B1491157}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3C9128AD-B677-460B-A1E1-D5B8B1491157}.Debug|ARM.ActiveCfg = Debug|Any CPU + {3C9128AD-B677-460B-A1E1-D5B8B1491157}.Debug|ARM.Build.0 = Debug|Any CPU + {3C9128AD-B677-460B-A1E1-D5B8B1491157}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {3C9128AD-B677-460B-A1E1-D5B8B1491157}.Debug|ARM64.Build.0 = Debug|Any CPU + {3C9128AD-B677-460B-A1E1-D5B8B1491157}.Debug|x64.ActiveCfg = Debug|Any CPU + {3C9128AD-B677-460B-A1E1-D5B8B1491157}.Debug|x64.Build.0 = Debug|Any CPU + {3C9128AD-B677-460B-A1E1-D5B8B1491157}.Debug|x86.ActiveCfg = Debug|Any CPU + {3C9128AD-B677-460B-A1E1-D5B8B1491157}.Debug|x86.Build.0 = Debug|Any CPU + {3C9128AD-B677-460B-A1E1-D5B8B1491157}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3C9128AD-B677-460B-A1E1-D5B8B1491157}.Release|Any CPU.Build.0 = Release|Any CPU + {3C9128AD-B677-460B-A1E1-D5B8B1491157}.Release|ARM.ActiveCfg = Release|Any CPU + {3C9128AD-B677-460B-A1E1-D5B8B1491157}.Release|ARM.Build.0 = Release|Any CPU + {3C9128AD-B677-460B-A1E1-D5B8B1491157}.Release|ARM64.ActiveCfg = Release|Any CPU + {3C9128AD-B677-460B-A1E1-D5B8B1491157}.Release|ARM64.Build.0 = Release|Any CPU + {3C9128AD-B677-460B-A1E1-D5B8B1491157}.Release|x64.ActiveCfg = Release|Any CPU + {3C9128AD-B677-460B-A1E1-D5B8B1491157}.Release|x64.Build.0 = Release|Any CPU + {3C9128AD-B677-460B-A1E1-D5B8B1491157}.Release|x86.ActiveCfg = Release|Any CPU + {3C9128AD-B677-460B-A1E1-D5B8B1491157}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -4970,6 +4994,8 @@ Global {27725449-27B2-47ED-A2B3-738851E55C64} = {5B333C02-67B7-4A4C-AA58-2710C183292B} {64EA0021-231A-421F-A616-3973C0106E99} = {5B333C02-67B7-4A4C-AA58-2710C183292B} {DA7ADAF3-34FF-4B97-8306-EF490A7A713A} = {5B333C02-67B7-4A4C-AA58-2710C183292B} + {78374D80-5BE7-425D-BE62-AD8F26491112} = {55E00151-58A6-4E7D-9457-0BB8213B82F5} + {3C9128AD-B677-460B-A1E1-D5B8B1491157} = {78374D80-5BE7-425D-BE62-AD8F26491112} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {8D31C3AE-36FF-4667-A2A7-0E670245A59E} diff --git a/p08_BDD_EntityFramework/ex_042_008_InitializationStrategy/DbContextInitializer.cs b/p08_BDD_EntityFramework/ex_042_008_InitializationStrategy/DbContextInitializer.cs new file mode 100644 index 0000000..2435c2b --- /dev/null +++ b/p08_BDD_EntityFramework/ex_042_008_InitializationStrategy/DbContextInitializer.cs @@ -0,0 +1,53 @@ +// ======================================================================== +// +// Copyright (C) 2016-2017 MARC CHEVALDONNE +// marc.chevaldonne.free.fr +// +// Module : DbContextInitializer.cs +// Author : Marc Chevaldonné +// Creation date : 2016-10-17 +// +// ======================================================================== + +using Microsoft.EntityFrameworkCore; +using System; + +namespace ex_042_008_InitializationStrategy +{ + /// + /// initialiseur de stratégies... + /// + public static class DbContextInitializer + { + /// + /// les différentes stratégies de création de la base + /// + public enum InitializationStrategies + { + CreateDatabaseIfNotExists, + DropCreateDatabaseIfModelChanges, + DropCreateDatabaseAlways + } + public static void SetInitializer(DbContext context, InitializationStrategies strategy) + { + switch(strategy) + { + //par défaut : crée la base seulement si elle n'existe pas + default: + case InitializationStrategies.CreateDatabaseIfNotExists: + context.Database.EnsureCreated(); + break; + + //recrée la base même si elle existe déjà + case InitializationStrategies.DropCreateDatabaseAlways: + context.Database.EnsureDeleted(); + context.Database.EnsureCreated(); + break; + + //recrée la base seulement si le modèle change : impossible aujourd'hui en Entity Framework Core... + case InitializationStrategies.DropCreateDatabaseIfModelChanges: + throw new NotImplementedException("Le mode DropCreateDatabaseIfModelChanges ne peut pas encore exister sous Entity Framework Core"); + } + } + } +} diff --git a/p08_BDD_EntityFramework/ex_042_008_InitializationStrategy/Nounours.cs b/p08_BDD_EntityFramework/ex_042_008_InitializationStrategy/Nounours.cs new file mode 100644 index 0000000..f97eb1c --- /dev/null +++ b/p08_BDD_EntityFramework/ex_042_008_InitializationStrategy/Nounours.cs @@ -0,0 +1,104 @@ +// ======================================================================== +// +// Copyright (C) 2016-2017 MARC CHEVALDONNE +// marc.chevaldonne.free.fr +// +// Module : Nounours.cs +// Author : Marc Chevaldonné +// Creation date : 2016-10-17 +// +// ======================================================================== + +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ex_042_008_InitializationStrategy +{ + /// + /// Nounours est une classe POCO, i.e. Plain Old CLR Object. + /// + [Table("TableNounours")] + public class Nounours + { + [Key] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public Guid UniqueId + { + get; set; + } + + [Required] + [MaxLength(256)] + public string Nom + { + get; + set; + } + + [Column("Naissance")] + public DateTime DateDeNaissance + { + get; + set; + } + + [NotMapped] + public int NbPoils + { + get; + set; + } + + /// + /// returns a hash code in order to use this class in hash table + /// + /// hash code + public override int GetHashCode() + { + return Nom.GetHashCode(); + } + + /// + /// checks if the "right" object is equal to this Nounours or not + /// + /// the other object to be compared with this Nounours + /// true if equals, false if not + public override bool Equals(object right) + { + //check null + if (object.ReferenceEquals(right, null)) + { + return false; + } + + if (object.ReferenceEquals(this, right)) + { + return true; + } + + if (this.GetType() != right.GetType()) + { + return false; + } + + return this.Equals(right as Nounours); + } + + /// + /// checks if this Nounours is equal to the other Nounours + /// + /// the other Nounours to be compared with + /// true if equals + public bool Equals(Nounours other) + { + return (this.Nom.Equals(other.Nom) && this.DateDeNaissance == other.DateDeNaissance); + } + + public override string ToString() + { + return $"{UniqueId}: {Nom} ({DateDeNaissance:dd/MM/yyyy}, {NbPoils} poils)"; + } + + } +} diff --git a/p08_BDD_EntityFramework/ex_042_008_InitializationStrategy/NounoursDBEntities.cs b/p08_BDD_EntityFramework/ex_042_008_InitializationStrategy/NounoursDBEntities.cs new file mode 100644 index 0000000..983fbd9 --- /dev/null +++ b/p08_BDD_EntityFramework/ex_042_008_InitializationStrategy/NounoursDBEntities.cs @@ -0,0 +1,29 @@ +// ======================================================================== +// +// Copyright (C) 2016-2017 MARC CHEVALDONNE +// marc.chevaldonne.free.fr +// +// Module : NounoursDBEntities.cs +// Author : Marc Chevaldonné +// Creation date : 2016-10-17 +// +// ======================================================================== + +using Microsoft.EntityFrameworkCore; + +namespace ex_042_008_InitializationStrategy +{ + /// + /// La classe qui dérive de DbContext est celle qui permettra de faire les opérations CRUD sur le modèle. + /// Cette classe contient un DbSet pour permettre de réaliser des opérations CRUD sur le type T, ici Nounours. + /// + class NounoursDBEntities : DbContext + { + public virtual DbSet NounoursSet { get; set; } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=ex_042_008_InitializationStrategy.Nounours.mdf;Trusted_Connection=True;"); + } + } +} diff --git a/p08_BDD_EntityFramework/ex_042_008_InitializationStrategy/Program.cs b/p08_BDD_EntityFramework/ex_042_008_InitializationStrategy/Program.cs new file mode 100644 index 0000000..92caf98 --- /dev/null +++ b/p08_BDD_EntityFramework/ex_042_008_InitializationStrategy/Program.cs @@ -0,0 +1,108 @@ +// ======================================================================== +// +// Copyright (C) 2016-2017 MARC CHEVALDONNE +// marc.chevaldonne.free.fr +// +// Module : Program.cs +// Author : Marc Chevaldonné +// Creation date : 2016-10-17 +// +// ======================================================================== + +using System; +using static System.Console; +using System.Linq; + +namespace ex_042_008_InitializationStrategy +{ + /// + /// Cet exemple présente les différentes stratégies d'initialisation de la base de données. + /// + /// Dans Entity Framework 6 pour .NET Framework (cf. ex_042_004 des exemples .NET Framework), il existe des stratégies d'initialisation. + /// Il n'y a malheureusement pas d'équivalent pour Entity Framework Core. + /// + /// Cet exemple reprend le 042_002 tout en proposant une méthode permettant de modifier les stratégies d'initialisation. + /// Pour cela, cet exemple propose l'écriture d'une classe statique DbContextInitializer, mais toutes les stratégies ne sont néanmoins pas reproductibles. + /// + class Program + { + static void Main(string[] args) + { + OutputEncoding = System.Text.Encoding.UTF8; + + Nounours chewie = new Nounours { Nom = "Chewbacca", DateDeNaissance = new DateTime(1977, 5, 27), NbPoils = 1234567 }; + Nounours yoda = new Nounours { Nom = "Yoda", DateDeNaissance = new DateTime(1980, 5, 21), NbPoils = 3 }; + Nounours ewok = new Nounours { Nom = "Ewok", DateDeNaissance = new DateTime(1983, 5, 25), NbPoils = 3456789 }; + Nounours trixi = new Nounours { Nom = "Trixi", DateDeNaissance = new DateTime(2015, 8, 15), NbPoils = 0 }; + Nounours Roudoudou = new Nounours { Nom = "Roudoudou", DateDeNaissance = new DateTime(2015, 8, 14), NbPoils = 2000 }; + + try + { + using (NounoursDBEntities db = new NounoursDBEntities()) + { + //choix de la stratégie + DbContextInitializer.SetInitializer(db, DbContextInitializer.InitializationStrategies.CreateDatabaseIfNotExists); + //DbContextInitializer.SetInitializer(db, DbContextInitializer.InitializationStrategies.DropCreateDatabaseAlways); + //DbContextInitializer.SetInitializer(db, DbContextInitializer.InitializationStrategies.DropCreateDatabaseIfModelChanges); + + if (db.NounoursSet.Count() > 0) + { + WriteLine("La base n'est pas vide !"); + foreach (var n in db.NounoursSet) + { + WriteLine($"\t{n}"); + } + WriteLine("début du nettoyage..."); + } + foreach (var n in db.NounoursSet.ToArray()) + { + WriteLine($"Suppression de {n}"); + db.NounoursSet.Remove(n); + } + + WriteLine("Base avant sauvegarde des changements :"); + foreach (var n in db.NounoursSet) + { + WriteLine($"\t{n}"); + } + db.SaveChanges(); + WriteLine("Base après sauvegarde des changements :"); + foreach (var n in db.NounoursSet) + { + WriteLine($"\t{n}"); + } + + db.NounoursSet.AddRange(new Nounours[] { chewie, yoda, ewok, trixi, Roudoudou }); + + db.SaveChanges(); + WriteLine("Base après ajout des 3 nounours et sauvegarde des changements :"); + foreach (var n in db.NounoursSet) + { + WriteLine($"\t{n}"); + } + + } + } + catch(NotImplementedException exception) + { + WriteLine(exception.Message); + } + catch (Exception) + { + WriteLine("Votre base de données n'existe pas. C'est peut-être la première fois que vous exécutez cet exemple."); + WriteLine("Pour créer la base de données, suivez les instructions suivantes (que vous retrouvez en commentaires dans la classe Program) :"); + WriteLine("Pour créer la base, ouvrez un invite de commandes et placez-vous dans le dossier de ce projet, ou bien,"); + WriteLine("- dans Visual Studio ouvrez la Console du Gestionnaire de package (Outils -> Gestionnaire de package NuGet -> Console du Gestionnaire de package),"); + WriteLine("- dans cette Console, vous devriez être dans le dossier de la solution, déplacez-vous dans celui du projet (ici : cd ex_042_004_EF_CF_InitializationStrategy)"); + WriteLine("- tapez : dotnet restore (pour restaurer les packages .NET Core)"); + WriteLine("- tapez : dotnet ef migrations add MyFirstMigration"); + WriteLine(" note : vous pourrez détruire le dossier Migrations une fois la base créée"); + WriteLine("- tapez : dotnet ef database update"); + WriteLine(" Ceci génère la base de données en utilisant la migration, et en particulier votre classe DBContext et vos classes POCO."); + WriteLine("\nDans cet exemple, une base de données SQLServer est créée et en particulier la table Nounours.mdf"); + } + + ReadLine(); + } + } +} diff --git a/p08_BDD_EntityFramework/ex_042_008_InitializationStrategy/ex_042_008_InitializationStrategy.csproj b/p08_BDD_EntityFramework/ex_042_008_InitializationStrategy/ex_042_008_InitializationStrategy.csproj new file mode 100644 index 0000000..dc4bf52 --- /dev/null +++ b/p08_BDD_EntityFramework/ex_042_008_InitializationStrategy/ex_042_008_InitializationStrategy.csproj @@ -0,0 +1,12 @@ + + + + Exe + netcoreapp3.0 + + + + + + + diff --git a/p08_BDD_EntityFramework/temp.md b/p08_BDD_EntityFramework/temp.md index 42550d6..fa7ee76 100644 --- a/p08_BDD_EntityFramework/temp.md +++ b/p08_BDD_EntityFramework/temp.md @@ -12,7 +12,7 @@ * ? nullable reference types => navigating (include, theninclude) ##### creating a model (42) * V 001, 002, 003 entity types, entity properties -* 004, 005, keys, generated values +* V 004, 005, 006 keys, 007 generated values * ? backing fields? * initialization strategy, seeding data * shadow properties