// ========================================================================
//
// Copyright (C) 2016-2017 MARC CHEVALDONNE
//                         marc.chevaldonne.free.fr
//
// Module        : AlbumArtisteDBEntities.cs
// Author        : Marc Chevaldonné
// Creation date : 2016-10-23
//
// ========================================================================

using Microsoft.EntityFrameworkCore;
using System;

namespace ex_042_011_EF_CF_Many_to_Many_FluentAPI
{
    /// <summary>
    /// 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<T> pour permettre de réaliser des opérations CRUD sur les types T, ici Album et Artiste.
    /// </summary>
    public class AlbumArtisteDBEntities : DbContext
    {
        public virtual DbSet<ArtisteEF> Artistes { get; set; }
        public virtual DbSet<AlbumEF> Albums { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=ex_042_011_EF_CF_Many_to_Many_FluentAPI.mdf;Trusted_Connection=True;");
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            //création de la table Albums
            modelBuilder.Entity<AlbumEF>().ToTable("Albums"); //nom de la table
            modelBuilder.Entity<AlbumEF>().HasKey(a => a.UniqueId); //définition de la clé primaire
            modelBuilder.Entity<AlbumEF>().Property(a => a.UniqueId)
                                           .ValueGeneratedOnAdd(); //définition du mode de génération de la clé : génération à l'insertion

            //création de la table "Artistes"
            modelBuilder.Entity<ArtisteEF>().ToTable("Artistes"); // nom de la table
            modelBuilder.Entity<ArtisteEF>().HasKey(a => a.UniqueId); //définition de la clé primaire
            modelBuilder.Entity<ArtisteEF>().Property(a => a.UniqueId)
                                                .ValueGeneratedOnAdd(); // définition du mode de génération de la clé : pas de génération automatique

            //on demande au modelBuilder d'ignorer les types Album et Artiste dans la création des entities
            modelBuilder.Ignore(typeof(Album));
            modelBuilder.Ignore(typeof(Artiste));


            //ajoute deux shadow properties à la classe AlbumArtiste pour qu'elles soient utilisées comme clés étrangères
            modelBuilder.Entity<AlbumArtiste>().Property<Guid>("AlbumId");
            modelBuilder.Entity<AlbumArtiste>().Property<Guid>("ArtisteId");
            //ajoute les mêmes aux entités AlbumEF et ArtisteEF
            modelBuilder.Entity<AlbumEF>().Property<Guid>("AlbumId");   
            modelBuilder.Entity<ArtisteEF>().Property<Guid>("ArtisteId");

            //crée une clé primaire à partir des deux propriétés précédentes
            modelBuilder.Entity<AlbumArtiste>().HasKey("AlbumId", "ArtisteId");

            //on demande au modèle d'ignorer les propriétés Artistes et Albums d'AlbumEF et ArtisteEF
            modelBuilder.Entity<AlbumEF>().Ignore("Artistes").Ignore("Album");
            modelBuilder.Entity<ArtisteEF>().Ignore("Albums").Ignore("Artiste");

            //lie l'entité AlbumArtiste à l'entité Album
            modelBuilder.Entity<AlbumArtiste>()
                .HasOne(aa => aa.Album)
                .WithMany(album => album.AlbumsArtistes)
                .HasForeignKey("AlbumId");

            //lie l'entité AlbumArtiste à l'entité Artiste
            modelBuilder.Entity<AlbumArtiste>()
                .HasOne(aa => aa.Artiste)
                .WithMany(artiste => artiste.ArtistesAlbums)
                .HasForeignKey("ArtisteId");

            base.OnModelCreating(modelBuilder);
        }
    }
}
