diff --git a/Exemples.sln b/Exemples.sln index bbf1321..251887e 100644 --- a/Exemples.sln +++ b/Exemples.sln @@ -578,7 +578,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "04. Relationships", "04. Re EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ex_042_010_SinglePropertyNavigation_conventions", "p08_BDD_EntityFramework\ex_042_010_SinglePropertyNavigation_conventions\ex_042_010_SinglePropertyNavigation_conventions.csproj", "{0D750BE3-0B5C-433C-A3A2-B70F390B4E93}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ex_042_011_SinglePropertyNavigation_FluentAPI", "p08_BDD_EntityFramework\ex_042_011_SinglePropertyNavigation_FluentAPI\ex_042_011_SinglePropertyNavigation_FluentAPI.csproj", "{CCC912CB-2962-441E-AB6B-97B0CB32AF11}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ex_042_011_SinglePropertyNavigation_FluentAPI", "p08_BDD_EntityFramework\ex_042_011_SinglePropertyNavigation_FluentAPI\ex_042_011_SinglePropertyNavigation_FluentAPI.csproj", "{CCC912CB-2962-441E-AB6B-97B0CB32AF11}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ex_042_012_OneToOne_conventions", "p08_BDD_EntityFramework\ex_042_012_OneToOne_conventions\ex_042_012_OneToOne_conventions.csproj", "{762C349D-5685-43FA-A077-2F3BDD07C898}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -4776,6 +4778,26 @@ Global {CCC912CB-2962-441E-AB6B-97B0CB32AF11}.Release|x64.Build.0 = Release|Any CPU {CCC912CB-2962-441E-AB6B-97B0CB32AF11}.Release|x86.ActiveCfg = Release|Any CPU {CCC912CB-2962-441E-AB6B-97B0CB32AF11}.Release|x86.Build.0 = Release|Any CPU + {762C349D-5685-43FA-A077-2F3BDD07C898}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {762C349D-5685-43FA-A077-2F3BDD07C898}.Debug|Any CPU.Build.0 = Debug|Any CPU + {762C349D-5685-43FA-A077-2F3BDD07C898}.Debug|ARM.ActiveCfg = Debug|Any CPU + {762C349D-5685-43FA-A077-2F3BDD07C898}.Debug|ARM.Build.0 = Debug|Any CPU + {762C349D-5685-43FA-A077-2F3BDD07C898}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {762C349D-5685-43FA-A077-2F3BDD07C898}.Debug|ARM64.Build.0 = Debug|Any CPU + {762C349D-5685-43FA-A077-2F3BDD07C898}.Debug|x64.ActiveCfg = Debug|Any CPU + {762C349D-5685-43FA-A077-2F3BDD07C898}.Debug|x64.Build.0 = Debug|Any CPU + {762C349D-5685-43FA-A077-2F3BDD07C898}.Debug|x86.ActiveCfg = Debug|Any CPU + {762C349D-5685-43FA-A077-2F3BDD07C898}.Debug|x86.Build.0 = Debug|Any CPU + {762C349D-5685-43FA-A077-2F3BDD07C898}.Release|Any CPU.ActiveCfg = Release|Any CPU + {762C349D-5685-43FA-A077-2F3BDD07C898}.Release|Any CPU.Build.0 = Release|Any CPU + {762C349D-5685-43FA-A077-2F3BDD07C898}.Release|ARM.ActiveCfg = Release|Any CPU + {762C349D-5685-43FA-A077-2F3BDD07C898}.Release|ARM.Build.0 = Release|Any CPU + {762C349D-5685-43FA-A077-2F3BDD07C898}.Release|ARM64.ActiveCfg = Release|Any CPU + {762C349D-5685-43FA-A077-2F3BDD07C898}.Release|ARM64.Build.0 = Release|Any CPU + {762C349D-5685-43FA-A077-2F3BDD07C898}.Release|x64.ActiveCfg = Release|Any CPU + {762C349D-5685-43FA-A077-2F3BDD07C898}.Release|x64.Build.0 = Release|Any CPU + {762C349D-5685-43FA-A077-2F3BDD07C898}.Release|x86.ActiveCfg = Release|Any CPU + {762C349D-5685-43FA-A077-2F3BDD07C898}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -5048,6 +5070,7 @@ Global {C7672736-AA73-4B7E-B5C6-A7A984216372} = {55E00151-58A6-4E7D-9457-0BB8213B82F5} {0D750BE3-0B5C-433C-A3A2-B70F390B4E93} = {C7672736-AA73-4B7E-B5C6-A7A984216372} {CCC912CB-2962-441E-AB6B-97B0CB32AF11} = {C7672736-AA73-4B7E-B5C6-A7A984216372} + {762C349D-5685-43FA-A077-2F3BDD07C898} = {C7672736-AA73-4B7E-B5C6-A7A984216372} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {8D31C3AE-36FF-4667-A2A7-0E670245A59E} diff --git a/p08_BDD_EntityFramework/ex_042_012_OneToOne_conventions/CarnetDeSante.cs b/p08_BDD_EntityFramework/ex_042_012_OneToOne_conventions/CarnetDeSante.cs new file mode 100644 index 0000000..2d1b517 --- /dev/null +++ b/p08_BDD_EntityFramework/ex_042_012_OneToOne_conventions/CarnetDeSante.cs @@ -0,0 +1,48 @@ +// ======================================================================== +// +// Copyright (C) 2016-2017 MARC CHEVALDONNE +// marc.chevaldonne.free.fr +// +// Module : CarnetDeSante.cs +// Author : Marc Chevaldonné +// Creation date : 2016-10-18 +// +// ======================================================================== + +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ex_042_012_OneToOne_conventions +{ + /// + /// CarnetDeSante est une classe POCO, i.e. Plain Old CLR Object + /// Elle a une relation 1-1 avec la classe Nounours via la propriété Owner. + /// Notez l'annotation ForeignKey("Nounours") sur la propriété UniqueId qui indique qu'il ne faut pas générer + /// une clé primaire pour ces instances, mais utiliser celle du Owner associé + /// + [Table("Carnets")] + public class CarnetDeSante + { + [Key, ForeignKey("Owner")] + public int UniqueId + { + get; set; + } + + public DateTime LastModified + { + get; set; + } + + public virtual Nounours Owner + { + get; set; + } + + public override string ToString() + { + return $"{UniqueId} : carnet de {Owner.Nom}, modifié la dernière fois le {LastModified.ToString("d")}"; + } + } +} diff --git a/p08_BDD_EntityFramework/ex_042_012_OneToOne_conventions/Nounours.cs b/p08_BDD_EntityFramework/ex_042_012_OneToOne_conventions/Nounours.cs new file mode 100644 index 0000000..ec6c9aa --- /dev/null +++ b/p08_BDD_EntityFramework/ex_042_012_OneToOne_conventions/Nounours.cs @@ -0,0 +1,108 @@ +// ======================================================================== +// +// Copyright (C) 2016-2017 MARC CHEVALDONNE +// marc.chevaldonne.free.fr +// +// Module : Nounours.cs +// Author : Marc Chevaldonné +// Creation date : 2016-10-18 +// +// ======================================================================== + +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ex_042_012_OneToOne_conventions +{ + /// + /// Nounours est une classe POCO, i.e. Plain Old CLR Object. + /// Elle a une relation 1-1 avec la classe CarnetDeSante via la propriété Carnet. + /// La clé primaire est générée lors de l'insertion en table (et est utilisée dans la classe CarnetDeSante + /// pour faire l'association. cf. CarnetDeSante). + [Table("TableNounours")] + public class Nounours + { + [Key] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int UniqueId + { + get; set; + } + + public virtual CarnetDeSante Carnet { 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_012_OneToOne_conventions/NounoursDBEntities.cs b/p08_BDD_EntityFramework/ex_042_012_OneToOne_conventions/NounoursDBEntities.cs new file mode 100644 index 0000000..91a9aea --- /dev/null +++ b/p08_BDD_EntityFramework/ex_042_012_OneToOne_conventions/NounoursDBEntities.cs @@ -0,0 +1,30 @@ +// ======================================================================== +// +// Copyright (C) 2016-2017 MARC CHEVALDONNE +// marc.chevaldonne.free.fr +// +// Module : NounoursDBEntities.cs +// Author : Marc Chevaldonné +// Creation date : 2016-10-18 +// +// ======================================================================== + +using Microsoft.EntityFrameworkCore; + +namespace ex_042_012_OneToOne_conventions +{ + /// + /// La classe qui dérive de DbContext est celle qui permettra de faire les opérations CRUD sur le modèle. + /// Cette classe contient deux DbSet pour permettre de réaliser des opérations CRUD sur les types T, ici Nounours et CarnetDeSante. + /// + public class NounoursDBEntities : DbContext + { + public virtual DbSet NounoursSet { get; set; } + public virtual DbSet Carnets { get; set; } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + optionsBuilder.UseSqlite($"Data Source=ex_042_012_OneToOne_conventions.Nounours.db"); + } + } +} diff --git a/p08_BDD_EntityFramework/ex_042_012_OneToOne_conventions/Program.cs b/p08_BDD_EntityFramework/ex_042_012_OneToOne_conventions/Program.cs new file mode 100644 index 0000000..d33b472 --- /dev/null +++ b/p08_BDD_EntityFramework/ex_042_012_OneToOne_conventions/Program.cs @@ -0,0 +1,76 @@ +// ======================================================================== +// +// Copyright (C) 2016-2017 MARC CHEVALDONNE +// marc.chevaldonne.free.fr +// +// Module : Program.cs +// Author : Marc Chevaldonné +// Creation date : 2016-10-18 +// +// ======================================================================== + +using Microsoft.EntityFrameworkCore; +using System; +using static System.Console; + +namespace ex_042_012_OneToOne_conventions +{ + public class Program + { + /// + /// Cet exemple montre comment construire une relation 1-1 dans la base de données en utilisant les conventions de nommage Entity Framework. + /// + /// on utilise les données stubbées de MyStubDataInitializationStrategy + /// On affiche les Nounours et les Carnets de santé. + /// Constatez que les identifiants sont bien les mêmes à cause de la relation 1-1. + /// + static void Main(string[] args) + { + OutputEncoding = System.Text.Encoding.UTF8; + + try + { + //using (NounoursDBEntities db = new NounoursDBEntities()) + //{ + // //choix de la stratégie et remplissage avec des données stubbées + // //DbContextInitializer.Seed(db); + //} + using (NounoursDBEntities db = new NounoursDBEntities()) + { + WriteLine("nounours : "); + foreach (var n in db.NounoursSet.Include(n => n.Carnet)) + { + WriteLine($"\t{n}, LastModified: {n.Carnet.LastModified.ToString("d")}"); + } + + WriteLine("carnets de santé : "); + foreach (var c in db.Carnets) + { + WriteLine($"\t{c}"); + } + + } + } + 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_006_EF_CF_One_to_One)"); + 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_012_OneToOne_conventions/StubbedContext.cs b/p08_BDD_EntityFramework/ex_042_012_OneToOne_conventions/StubbedContext.cs new file mode 100644 index 0000000..5652b89 --- /dev/null +++ b/p08_BDD_EntityFramework/ex_042_012_OneToOne_conventions/StubbedContext.cs @@ -0,0 +1,27 @@ +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Text; + +namespace ex_042_012_OneToOne_conventions +{ + class StubbedContext : NounoursDBEntities + { + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + + modelBuilder.Entity().HasData( + new CarnetDeSante { UniqueId=1, LastModified = DateTime.Today }, + new CarnetDeSante { UniqueId=2, LastModified = new DateTime(1980, 5, 21) }, + new CarnetDeSante { UniqueId=3, LastModified = new DateTime(1983, 5, 25) } + ); + + modelBuilder.Entity().HasData( + new Nounours { UniqueId=1, Nom = "Chewbacca", DateDeNaissance = new DateTime(1977, 5, 27), NbPoils = 1234567 }, + new Nounours { UniqueId=2, Nom = "Yoda", DateDeNaissance = new DateTime(1980, 5, 21), NbPoils = 3 }, + new Nounours { UniqueId=3, Nom = "Ewok", DateDeNaissance = new DateTime(1983, 5, 25), NbPoils = 3456789 } + ); + } + } +} diff --git a/p08_BDD_EntityFramework/ex_042_012_OneToOne_conventions/ex_042_012_OneToOne_conventions.csproj b/p08_BDD_EntityFramework/ex_042_012_OneToOne_conventions/ex_042_012_OneToOne_conventions.csproj new file mode 100644 index 0000000..c302951 --- /dev/null +++ b/p08_BDD_EntityFramework/ex_042_012_OneToOne_conventions/ex_042_012_OneToOne_conventions.csproj @@ -0,0 +1,14 @@ + + + + Exe + netcoreapp3.0 + $(MSBuildProjectDirectory) + + + + + + + + diff --git a/p08_BDD_EntityFramework/temp.md b/p08_BDD_EntityFramework/temp.md index 40e5ed3..b937d76 100644 --- a/p08_BDD_EntityFramework/temp.md +++ b/p08_BDD_EntityFramework/temp.md @@ -16,8 +16,8 @@ * ? backing fields? * V 008, 009 seeding data * ###### relationships - * shadow properties - * single navigation property + * V 010, 011 shadow properties + * 010, 011, single navigation property * cascade delete * one to one * one to many