diff --git a/p08_BDD_EntityFramework/ex_042_003_EF_CF_Fluent_API/Nounours.cs b/p08_BDD_EntityFramework/ex_042_003_EF_CF_Fluent_API/Nounours.cs new file mode 100644 index 0000000..8cbf24b --- /dev/null +++ b/p08_BDD_EntityFramework/ex_042_003_EF_CF_Fluent_API/Nounours.cs @@ -0,0 +1,81 @@ +using System; + +namespace ex_042_003_EF_CF_Fluent_API +{ + public class Nounours + { + public Guid UniqueId + { + get; set; + } + + public string Nom + { + get; + set; + } + + public DateTime DateDeNaissance + { + get; + set; + } + + 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_003_EF_CF_Fluent_API/NounoursDBEntities.cs b/p08_BDD_EntityFramework/ex_042_003_EF_CF_Fluent_API/NounoursDBEntities.cs new file mode 100644 index 0000000..f4103e7 --- /dev/null +++ b/p08_BDD_EntityFramework/ex_042_003_EF_CF_Fluent_API/NounoursDBEntities.cs @@ -0,0 +1,67 @@ +using Microsoft.EntityFrameworkCore; + +namespace ex_042_003_EF_CF_Fluent_API +{ + /// + /// Contrairement aux 2 exemples précédents, nous n'utilisons pas les conventions d'écriture, ni les annotations de données pour utiliser créer la table + /// à partir de la classe Nounours. Nous allons cette fois-ci utiliser la Fluent API et réécrire dans la classe NounoursDBEntities dérivant de DbContext + /// de quelle manière créer la table à partir de la classe Nounours. + /// + /// Cette méthode est préférable dans les deux cas principaux suivants (et en particulier le 1er) : + /// - nous n'avons pas accès au code source de la classe Nounours ou bien nous n'avons pas le droit de le modifier, et les conventions d'écriture ne + /// correspondent pas à ce que nous souhaitons réaliser. + /// - nous ne souhaitons pas "polluer" la classe POCO avec des annotations de données. + /// + /// L'inconvénient majeur et évident de cette méthode est que la lecture et la maintenance sont plus compliquées. + /// + /// Pour utiliser la Fluent API et décrire de quelle manière créer la table à partir de la classe POCO, il faut réécrire la méthode virtuelle OnModelCreating + /// (cf. commentaires de la méthode ci-dessous). + /// + /// L'exemple ci-dessous recrée exactement la même table que dans l'exemple précédent. + /// + class NounoursDBEntities : DbContext + { + public virtual DbSet NounoursSet { get; set; } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=ex_042_003_EF_CF_Fluent_API.Nounours.mdf;Trusted_Connection=True;"); + } + + /// + /// méthode appelée lors de la création du modèle. + /// + /// + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + //ici on précise comment s'appellera la table associée à la classe POCO Nounours + //équivalent du [Table("TableNounours")] avec les annotations de données + modelBuilder.Entity().ToTable("TableNounours"); + + //ici on précise que la propriété UniqueId de Nounours est la clef primaire + //équivalent de [Key] devant la propriété UniqueId dans Nounours + modelBuilder.Entity().HasKey(n => n.UniqueId); + + //ici on explique que c'est lors de l'insertion en base que la clef primaire sera générée + //équivalent de [DatabaseGenerated(DatabaseGeneratedOption.Identity)] devant la propriété UniqueId de Nounours + modelBuilder.Entity().Property(n => n.UniqueId).ValueGeneratedOnAdd(); + //HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity); + + //ici on précise que la propriété Nom est obligatoire et que sa taille maximale est de 256 caractères + //Notez l'utilisation des méthodes chaînées ! Trop beau ! Tellement pratique, intuitif et évident... + //équivalent de [Required] et [MaxLength(256)] devant la propriété Nom de Nounours + modelBuilder.Entity().Property(n => n.Nom).IsRequired() + .HasMaxLength(256); + + //ici on donne un nom à la colonne associée à la propriété DateDeNaissance + //équivalent de [Column("Naissance")] devant la propriété DateDeNaissance de Nounours + modelBuilder.Entity().Property(n => n.DateDeNaissance).HasColumnName("Naissance").HasColumnType("date"); + + //ici on précise que la propriété NbPoils ne sera pas insérée en base + //équivalent de [NotMapped] devant la propriété NbPoils de Nounours + modelBuilder.Entity().Ignore(n => n.NbPoils); + + base.OnModelCreating(modelBuilder); + } + } +}