diff --git a/Sources/API_LoL/API_LoL.csproj b/Sources/API_LoL/API_LoL.csproj index 5ada54d..a8c4de7 100644 --- a/Sources/API_LoL/API_LoL.csproj +++ b/Sources/API_LoL/API_LoL.csproj @@ -9,6 +9,8 @@ + + diff --git a/Sources/API_LoL/Controllers/ChampionsController.cs b/Sources/API_LoL/Controllers/ChampionsController.cs index ce8b87e..1b2b021 100644 --- a/Sources/API_LoL/Controllers/ChampionsController.cs +++ b/Sources/API_LoL/Controllers/ChampionsController.cs @@ -13,7 +13,9 @@ using System.Xml.Linq; namespace API_LoL.Controllers { - [Route("api/[controller]")] + //[Route("api/[controller]")] + [ApiVersion("1.0")] + [Route("api/v{version:apiVersion}/[controller]")] [ApiController] public class ChampionsController : ControllerBase { diff --git a/Sources/API_LoL/Controllers/ChampionsControllerVersioned.cs b/Sources/API_LoL/Controllers/ChampionsControllerVersioned.cs new file mode 100644 index 0000000..87598d9 --- /dev/null +++ b/Sources/API_LoL/Controllers/ChampionsControllerVersioned.cs @@ -0,0 +1,108 @@ +using Microsoft.AspNetCore.Mvc; +using Model; +using StubLib; +using DTO; +using DTO.Mapper; +using System.CodeDom.Compiler; + +namespace API_LoL.Controllers +{ + [ApiVersion("2.0")] + [ApiVersion("2.2")] + [Route("api/v{version:apiVersion}/versioned")] + [ApiController] + public class ChampionsControllerVersioned : ControllerBase + { + public ChampionsControllerVersioned(IDataManager Manager) + { + this.ChampionsManager = Manager.ChampionsMgr; + } + + private IChampionsManager ChampionsManager; + + // GET api//5 + + //[HttpGet] + //public async Task Get(String? name = null, String? skill = null, String? characteristic = null, int index = 0, int size = 10) + //{ + // if (size - index > 10) + // { + // return BadRequest(); + // } + // if (!string.IsNullOrEmpty(name)) + // { + // var list = await ChampionsManager.GetItemsByName(name, index, size); + // if (list.Count() != 0) + // { + // return Ok(list.Select(champion => champion?.ToDTO())); + // } + // else { return NoContent(); } + // } + // else if (!string.IsNullOrEmpty(skill)) + // { + // var list = await ChampionsManager.GetItemsBySkill(skill, index, size); + // if (list.Count() != 0) + // { + // return Ok(list.Select(champion => champion?.ToDTO())); + // } + // else { return NoContent(); } + // } + // else if (!string.IsNullOrEmpty(characteristic)) + // { + // var list = await ChampionsManager.GetItems(index, size); + // if (list.Count() != 0) + // { + // return Ok(list.Select(champion => champion?.ToDTO())); + // } + // else { return NoContent(); } + // } + // else + // { + // var list = await ChampionsManager.GetItems(index, size); + // if (list.Count() != 0) + // { + // return Ok(list.Select(champion => champion?.ToDTO())); + // } + // else { return NoContent(); } + // } + //} + + + //// POST api/ + //[HttpPost] + //public async Task Post(ChampionDTO champion) + //{ + // if (champion == null) + // { + // return UnprocessableEntity(); + // } + // else + // { + // await ChampionsManager.AddItem(champion.ToChampion()); + // return CreatedAtAction("Post", champion); + // } + //} + + //// PUT api//5 + //[HttpPut("{id}")] + //public void Put(int id, [FromBody] string value) + //{ + //} + + //// DELETE api//5 + //[HttpDelete("{id}")] + //public void Delete(int id) + //{ + //} + + + ///---------- Versioning ----------/// + [HttpGet, MapToApiVersion("2.0")] + public string GetThatOnlySayHello() => "Hello v2.0!"; + + + //! FIXME : not working, mais avec la version 2.0 ca marche ! + [HttpGet, MapToApiVersion("2.2")] + public string GetThatOnlySayHelloV2() => "Hello but i'm from v2.2!"; + } +} diff --git a/Sources/API_LoL/Program.cs b/Sources/API_LoL/Program.cs index d4fb3b8..c192eac 100644 --- a/Sources/API_LoL/Program.cs +++ b/Sources/API_LoL/Program.cs @@ -1,24 +1,65 @@ +using API_LoL; +using Microsoft.AspNetCore.Mvc.ApiExplorer; +using Microsoft.AspNetCore.Mvc.Versioning; using Model; using StubLib; var builder = WebApplication.CreateBuilder(args); -// Add services to the container. -builder.Services.AddControllers(); +//Versioning + +///NOT WORKING WHEN CHANGING VERSIONS : +/// voir sur https://blog.christian-schou.dk/how-to-use-api-versioning-in-net-core-web-api/ rubrique "Configure SwaggerOptions" +/// (mais requiere l'injection de dépendance). +/// Sinon, code plus simple disponible par le prof + + + +// Add ApiExplorer to discover versions +builder.Services.AddVersionedApiExplorer(setup => +{ + setup.GroupNameFormat = "'v'VVV"; + setup.SubstituteApiVersionInUrl = true; +}); + // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); +builder.Services.ConfigureOptions(); + + +builder.Services.AddApiVersioning(o => o.ApiVersionReader = new UrlSegmentApiVersionReader()); + +// Add services to the container. +builder.Services.AddControllers(); + + + builder.Services.AddScoped(); + + + var app = builder.Build(); +var apiVersionDescriptionProvider = app.Services.GetRequiredService(); + + // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); - app.UseSwaggerUI(); + app.UseSwaggerUI(options => + { + + foreach (var description in apiVersionDescriptionProvider.ApiVersionDescriptions) + { + options.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json", + description.GroupName.ToUpperInvariant()); + } + }); } app.UseHttpsRedirection(); diff --git a/Sources/API_LoL/SwaggerOptions.cs b/Sources/API_LoL/SwaggerOptions.cs new file mode 100644 index 0000000..46ad759 --- /dev/null +++ b/Sources/API_LoL/SwaggerOptions.cs @@ -0,0 +1,61 @@ +using Microsoft.AspNetCore.Mvc.ApiExplorer; +using Microsoft.Extensions.Options; +using Microsoft.OpenApi.Models; +using Swashbuckle.AspNetCore.SwaggerGen; + +namespace API_LoL +{ + public class ConfigureSwaggerOptions : IConfigureNamedOptions + { + private readonly IApiVersionDescriptionProvider _provider; + + public ConfigureSwaggerOptions(IApiVersionDescriptionProvider provider) + { + _provider = provider; + } + + /// + /// Configure each API discovered for Swagger Documentation + /// + /// + public void Configure(SwaggerGenOptions options) + { + // add swagger document for every API version discovered + foreach (var description in _provider.ApiVersionDescriptions) + { + options.SwaggerDoc(description.GroupName, CreateVersionInfo(description)); + } + } + + /// + /// Configure Swagger Options. Inherited from the Interface + /// + /// + /// + public void Configure(string name, SwaggerGenOptions options) + { + Configure(options); + } + + /// + /// Create information about the version of the API + /// + /// + /// Information about the API + private OpenApiInfo CreateVersionInfo(ApiVersionDescription desc) + { + var info = new OpenApiInfo() + { + Title = ".NET Core (.NET 6) Web API", + Version = desc.ApiVersion.ToString() + }; + + if (desc.IsDeprecated) + { + info.Description += " This API version has been deprecated. Please use one of the new APIs available from the explorer."; + } + + return info; + } + } +} diff --git a/Sources/EF_UT/EntityTest.cs b/Sources/EF_UT/EntityTest.cs index 4122418..5fd0afb 100644 --- a/Sources/EF_UT/EntityTest.cs +++ b/Sources/EF_UT/EntityTest.cs @@ -23,11 +23,12 @@ namespace EF_UT using (var context = new LoLDbContext(options)) { - ChampionEntity chewie = new ChampionEntity("Chewbacca", "", ""); - ChampionEntity yoda = new ChampionEntity("Yoda", "", ""); - ChampionEntity ewok = new ChampionEntity("Ewok", "", ""); - + ChampionEntity chewie = new ChampionEntity { Name = "Chewbacca", Bio = "", Icon = "" }; + ChampionEntity yoda = new ChampionEntity{ Name = "Yoda", Bio = "", Icon = "" }; + ChampionEntity ewok = new ChampionEntity{ Name = "Ewok", Bio = "", Icon = "" }; + //SkinEntity defaulSkin = new SkinEntity("Skin Default", chewie); + //chewie.AddSkin(defaulSkin); Console.WriteLine("Creates and inserts new Champion for tests"); context.Add(chewie); context.Add(yoda); @@ -54,9 +55,9 @@ namespace EF_UT //prepares the database with one instance of the context using (var context = new LoLDbContext(options)) { - ChampionEntity chewie = new ChampionEntity("Chewbacca", "ewa", ""); - ChampionEntity yoda = new ChampionEntity("Yoda", "wewo", ""); - ChampionEntity ewok = new ChampionEntity("Ewok", "", ""); + ChampionEntity chewie = new ChampionEntity{ Name = "Chewbacca", Bio = "ewa", Icon = "" }; + ChampionEntity yoda = new ChampionEntity{ Name = "Yoda", Bio = "wewo", Icon = "" }; + ChampionEntity ewok = new ChampionEntity{ Name = "Ewok", Bio = "", Icon = "" }; context.Add(chewie); context.Add(yoda); diff --git a/Sources/EntityFramework/ChampionEntity.cs b/Sources/EntityFramework/ChampionEntity.cs index 02e5a2d..c090b08 100644 --- a/Sources/EntityFramework/ChampionEntity.cs +++ b/Sources/EntityFramework/ChampionEntity.cs @@ -32,19 +32,32 @@ namespace EntityFramework //public ImmutableHashSet Skills => skills.ToImmutableHashSet(); //private HashSet skills = new HashSet(); - private ICollection Skills { get; set; } + public ICollection Skills { get; set; } = new Collection(); + + //public ReadOnlyCollection Skins { get; private set; } + //private List skins = new(); + + public ICollection skins { get; set; } = new Collection(); + + //public LargeImageEntity? Image { get; set; } ====> voir pour faire "plus propre" => créé une table pour l'entity Largeimage + public string? Image { get; set; } // Pour le many to many Champion *<---->* RunePage public ICollection RunePageEntities{ get; set; } - public ChampionEntity(string name,string bio,string icon) { - this.Name = name; - this.Bio = bio; - this.Icon = icon; - Skills= new List(); - } + /// + /// pas besoin de constructeur ! (sans lui, il est possible d'utiliser la syntaxe utilisé dans le stubbedbDBCOntext) + /// + /// + //public ChampionEntity(string name,string bio,string icon) { + // this.Name = name; + // this.Bio = bio; + // this.Icon = icon; + // Skills= new List(); + // //Skins = new ReadOnlyCollection(skins); + //} public override string ToString() { @@ -58,5 +71,15 @@ namespace EntityFramework public void RemoveSkill(SkillEntity skill) => Skills.Remove(skill); + + public bool AddSkin(SkinEntity skin) + { + if (skins.Contains(skin)) + return false; + skins.Add(skin); + return true; + } + + } } diff --git a/Sources/EntityFramework/LargeImageEntity.cs b/Sources/EntityFramework/LargeImageEntity.cs new file mode 100644 index 0000000..b925a83 --- /dev/null +++ b/Sources/EntityFramework/LargeImageEntity.cs @@ -0,0 +1,22 @@ +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EntityFramework +{ + + public class LargeImageEntity + { + public int Id { get; set; } + public string Base64 { get; set; } + + //public LargeImageEntity(string base64) + //{ + // Base64 = base64; + //} + } +} diff --git a/Sources/EntityFramework/LoLDbContext.cs b/Sources/EntityFramework/LoLDbContext.cs index 354aa89..57d65a8 100644 --- a/Sources/EntityFramework/LoLDbContext.cs +++ b/Sources/EntityFramework/LoLDbContext.cs @@ -11,6 +11,11 @@ namespace EntityFramework { public DbSet Champions { get; set; } + public DbSet Skins { get; set; } + + public DbSet Image { get; set; } + + public DbSet Rune { get; set; } public DbSet RunePage { get; set; } @@ -53,6 +58,24 @@ namespace EntityFramework + /// One to many + /// ChampionEntity 1 ---> * SkinEntity + //création de la table Skin + modelBuilder.Entity().HasKey(skin => skin.Name); //définition de la clé primaire + modelBuilder.Entity().Property(skin => skin.Name) + .ValueGeneratedOnAdd(); //définition du mode de génération de la clé : génération à l'insertion + + // Add the shadow property to the model + modelBuilder.Entity() + .Property("ChampionEntityForeignKey"); + + // Use the shadow property as a foreign key + modelBuilder.Entity() + .HasOne(skin => skin.Champion) + .WithMany(champion => champion.skins) + .HasForeignKey("ChampionEntityForeignKey"); + + diff --git a/Sources/EntityFramework/Mapper/ChampionMapper.cs b/Sources/EntityFramework/Mapper/ChampionMapper.cs index 862264d..14942d1 100644 --- a/Sources/EntityFramework/Mapper/ChampionMapper.cs +++ b/Sources/EntityFramework/Mapper/ChampionMapper.cs @@ -10,7 +10,7 @@ namespace EntityFramework.Mapper public static class ChampionMapper { public static ChampionEntity ToEntity(this Champion champion) { - return new ChampionEntity(champion.Name, champion.Bio, champion.Icon); + return new ChampionEntity { Name = champion.Name, Bio = champion.Bio, Icon = champion.Icon }; } } } diff --git a/Sources/EntityFramework/Migrations/20230312170120_stubMig.Designer.cs b/Sources/EntityFramework/Migrations/20230312170120_stubMig.Designer.cs deleted file mode 100644 index 2b24874..0000000 --- a/Sources/EntityFramework/Migrations/20230312170120_stubMig.Designer.cs +++ /dev/null @@ -1,83 +0,0 @@ -// -using EntityFramework; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; - -#nullable disable - -namespace EntityFramework.Migrations -{ - [DbContext(typeof(LoLDBContextWithStub))] - [Migration("20230312170120_stubMig")] - partial class stubMig - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder.HasAnnotation("ProductVersion", "7.0.2"); - - modelBuilder.Entity("EntityFramework.ChampionEntity", b => - { - b.Property("Name") - .HasMaxLength(50) - .HasColumnType("TEXT"); - - b.Property("Bio") - .IsRequired() - .HasMaxLength(500) - .HasColumnType("string") - .HasColumnName("Bio"); - - b.Property("Icon") - .IsRequired() - .HasColumnType("TEXT"); - - b.HasKey("Name"); - - b.ToTable("Champion", (string)null); - - b.HasData( - new - { - Name = "Akali", - Bio = "", - Icon = "" - }, - new - { - Name = "Aatrox", - Bio = "", - Icon = "" - }, - new - { - Name = "Ahri", - Bio = "", - Icon = "" - }, - new - { - Name = "Akshan", - Bio = "", - Icon = "" - }, - new - { - Name = "Bard", - Bio = "", - Icon = "" - }, - new - { - Name = "Alistar", - Bio = "", - Icon = "" - }); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Sources/EntityFramework/Migrations/20230312170120_stubMig.cs b/Sources/EntityFramework/Migrations/20230312170120_stubMig.cs deleted file mode 100644 index 3323fa4..0000000 --- a/Sources/EntityFramework/Migrations/20230312170120_stubMig.cs +++ /dev/null @@ -1,49 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional - -namespace EntityFramework.Migrations -{ - /// - public partial class stubMig : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "Champion", - columns: table => new - { - Name = table.Column(type: "TEXT", maxLength: 50, nullable: false), - Bio = table.Column(type: "string", maxLength: 500, nullable: false), - Icon = table.Column(type: "TEXT", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Champion", x => x.Name); - }); - - migrationBuilder.InsertData( - table: "Champion", - columns: new[] { "Name", "Bio", "Icon" }, - values: new object[,] - { - { "Aatrox", "", "" }, - { "Ahri", "", "" }, - { "Akali", "", "" }, - { "Akshan", "", "" }, - { "Alistar", "", "" }, - { "Bard", "", "" } - }); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "Champion"); - } - } -} diff --git a/Sources/EntityFramework/Migrations/20230315145258_myMig.Designer.cs b/Sources/EntityFramework/Migrations/20230315145258_myMig.Designer.cs new file mode 100644 index 0000000..34ce7d8 --- /dev/null +++ b/Sources/EntityFramework/Migrations/20230315145258_myMig.Designer.cs @@ -0,0 +1,175 @@ +// +using EntityFramework; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace EntityFramework.Migrations +{ + [DbContext(typeof(LoLDBContextWithStub))] + [Migration("20230315145258_myMig")] + partial class myMig + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "7.0.2"); + + modelBuilder.Entity("EntityFramework.ChampionEntity", b => + { + b.Property("Name") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("Bio") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("string") + .HasColumnName("Bio"); + + b.Property("Icon") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Image") + .HasColumnType("TEXT"); + + b.HasKey("Name"); + + b.ToTable("Champion", (string)null); + + b.HasData( + new + { + Name = "Akali", + Bio = "", + Icon = "" + }, + new + { + Name = "Aatrox", + Bio = "", + Icon = "" + }, + new + { + Name = "Ahri", + Bio = "", + Icon = "" + }, + new + { + Name = "Akshan", + Bio = "", + Icon = "" + }, + new + { + Name = "Bard", + Bio = "", + Icon = "" + }, + new + { + Name = "Alistar", + Bio = "", + Icon = "" + }); + }); + + modelBuilder.Entity("EntityFramework.LargeImageEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Base64") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Image"); + }); + + modelBuilder.Entity("EntityFramework.SkillEntity", b => + { + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("ChampionEntityName") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.HasKey("Name"); + + b.HasIndex("ChampionEntityName"); + + b.ToTable("SkillEntity"); + }); + + modelBuilder.Entity("EntityFramework.SkinEntity", b => + { + b.Property("Name") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("ChampionEntityForeignKey") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("Icon") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Image") + .HasColumnType("TEXT"); + + b.Property("Price") + .HasColumnType("REAL"); + + b.HasKey("Name"); + + b.HasIndex("ChampionEntityForeignKey"); + + b.ToTable("Skins"); + }); + + modelBuilder.Entity("EntityFramework.SkillEntity", b => + { + b.HasOne("EntityFramework.ChampionEntity", null) + .WithMany("Skills") + .HasForeignKey("ChampionEntityName"); + }); + + modelBuilder.Entity("EntityFramework.SkinEntity", b => + { + b.HasOne("EntityFramework.ChampionEntity", "Champion") + .WithMany("skins") + .HasForeignKey("ChampionEntityForeignKey"); + + b.Navigation("Champion"); + }); + + modelBuilder.Entity("EntityFramework.ChampionEntity", b => + { + b.Navigation("Skills"); + + b.Navigation("skins"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Sources/EntityFramework/Migrations/20230315145258_myMig.cs b/Sources/EntityFramework/Migrations/20230315145258_myMig.cs new file mode 100644 index 0000000..86b3a87 --- /dev/null +++ b/Sources/EntityFramework/Migrations/20230315145258_myMig.cs @@ -0,0 +1,122 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional + +namespace EntityFramework.Migrations +{ + /// + public partial class myMig : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Champion", + columns: table => new + { + Name = table.Column(type: "TEXT", maxLength: 50, nullable: false), + Bio = table.Column(type: "string", maxLength: 500, nullable: false), + Icon = table.Column(type: "TEXT", nullable: false), + Image = table.Column(type: "TEXT", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Champion", x => x.Name); + }); + + migrationBuilder.CreateTable( + name: "Image", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Base64 = table.Column(type: "TEXT", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Image", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "SkillEntity", + columns: table => new + { + Name = table.Column(type: "TEXT", nullable: false), + Type = table.Column(type: "INTEGER", nullable: false), + Description = table.Column(type: "TEXT", nullable: false), + ChampionEntityName = table.Column(type: "TEXT", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_SkillEntity", x => x.Name); + table.ForeignKey( + name: "FK_SkillEntity_Champion_ChampionEntityName", + column: x => x.ChampionEntityName, + principalTable: "Champion", + principalColumn: "Name"); + }); + + migrationBuilder.CreateTable( + name: "Skins", + columns: table => new + { + Name = table.Column(type: "TEXT", nullable: false), + Description = table.Column(type: "TEXT", nullable: true), + Icon = table.Column(type: "TEXT", nullable: false), + Image = table.Column(type: "TEXT", nullable: true), + Price = table.Column(type: "REAL", nullable: false), + ChampionEntityForeignKey = table.Column(type: "TEXT", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Skins", x => x.Name); + table.ForeignKey( + name: "FK_Skins_Champion_ChampionEntityForeignKey", + column: x => x.ChampionEntityForeignKey, + principalTable: "Champion", + principalColumn: "Name"); + }); + + migrationBuilder.InsertData( + table: "Champion", + columns: new[] { "Name", "Bio", "Icon", "Image" }, + values: new object[,] + { + { "Aatrox", "", "", null }, + { "Ahri", "", "", null }, + { "Akali", "", "", null }, + { "Akshan", "", "", null }, + { "Alistar", "", "", null }, + { "Bard", "", "", null } + }); + + migrationBuilder.CreateIndex( + name: "IX_SkillEntity_ChampionEntityName", + table: "SkillEntity", + column: "ChampionEntityName"); + + migrationBuilder.CreateIndex( + name: "IX_Skins_ChampionEntityForeignKey", + table: "Skins", + column: "ChampionEntityForeignKey"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Image"); + + migrationBuilder.DropTable( + name: "SkillEntity"); + + migrationBuilder.DropTable( + name: "Skins"); + + migrationBuilder.DropTable( + name: "Champion"); + } + } +} diff --git a/Sources/EntityFramework/Migrations/LoLDBContextWithStubModelSnapshot.cs b/Sources/EntityFramework/Migrations/LoLDBContextWithStubModelSnapshot.cs index ba61c51..1bbd357 100644 --- a/Sources/EntityFramework/Migrations/LoLDBContextWithStubModelSnapshot.cs +++ b/Sources/EntityFramework/Migrations/LoLDBContextWithStubModelSnapshot.cs @@ -32,6 +32,9 @@ namespace EntityFramework.Migrations .IsRequired() .HasColumnType("TEXT"); + b.Property("Image") + .HasColumnType("TEXT"); + b.HasKey("Name"); b.ToTable("Champion", (string)null); @@ -74,6 +77,95 @@ namespace EntityFramework.Migrations Icon = "" }); }); + + modelBuilder.Entity("EntityFramework.LargeImageEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Base64") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Image"); + }); + + modelBuilder.Entity("EntityFramework.SkillEntity", b => + { + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("ChampionEntityName") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.HasKey("Name"); + + b.HasIndex("ChampionEntityName"); + + b.ToTable("SkillEntity"); + }); + + modelBuilder.Entity("EntityFramework.SkinEntity", b => + { + b.Property("Name") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("ChampionEntityForeignKey") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("Icon") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Image") + .HasColumnType("TEXT"); + + b.Property("Price") + .HasColumnType("REAL"); + + b.HasKey("Name"); + + b.HasIndex("ChampionEntityForeignKey"); + + b.ToTable("Skins"); + }); + + modelBuilder.Entity("EntityFramework.SkillEntity", b => + { + b.HasOne("EntityFramework.ChampionEntity", null) + .WithMany("Skills") + .HasForeignKey("ChampionEntityName"); + }); + + modelBuilder.Entity("EntityFramework.SkinEntity", b => + { + b.HasOne("EntityFramework.ChampionEntity", "Champion") + .WithMany("skins") + .HasForeignKey("ChampionEntityForeignKey"); + + b.Navigation("Champion"); + }); + + modelBuilder.Entity("EntityFramework.ChampionEntity", b => + { + b.Navigation("Skills"); + + b.Navigation("skins"); + }); #pragma warning restore 612, 618 } } diff --git a/Sources/EntityFramework/Program.cs b/Sources/EntityFramework/Program.cs index 65ef614..818faa5 100644 --- a/Sources/EntityFramework/Program.cs +++ b/Sources/EntityFramework/Program.cs @@ -1,12 +1,13 @@ // See https://aka.ms/new-console-template for more information using EntityFramework; +using Microsoft.EntityFrameworkCore; -using( var context = new LoLDbContext()) +using ( var context = new LoLDbContext()) { - context.Add(new ChampionEntity("test","test","test") ); + //context.Add(new ChampionEntity{ Name = "test", Bio = "test", Icon = "test" } ); context.SaveChanges(); - ChampionEntity champ = context.Find(1); + ChampionEntity champ = context.Find("Akali"); if( champ != null) { @@ -20,18 +21,58 @@ using( var context = new LoLDbContext()) } //Test BDD Skills - ChampionEntity champSkill = new ChampionEntity("nomSkill", "bioSkill", "iconSkill"); + ChampionEntity champSkill = new ChampionEntity { Name="nomSkill", Bio="bioSkill", Icon="iconSkill" }; - SkillEntity s1 = new SkillEntity("Skill1", "desc", SkillType.Unknown); - SkillEntity s2 = new SkillEntity("Skill2", "desc2", SkillType.Ultimate); - SkillEntity s3 = new SkillEntity("Skill3", "desc3", SkillType.Passive); + //SkillEntity s1 = new SkillEntity { Name = "Skill1", Description = "desc", Type = SkillType.Unknown }; + SkillEntity s2 = new SkillEntity { Name="Skill2", Description="desc2", Type=SkillType.Ultimate }; + SkillEntity s3 = new SkillEntity { Name = "Skill3", Description = "desc3", Type = SkillType.Passive }; - champSkill.AddSkill(s1); + champSkill.AddSkill(new SkillEntity { Name = "Skill1", Description = "desc", Type = SkillType.Unknown }); champSkill.AddSkill(s2); champSkill.AddSkill(s3); context.Add(champSkill); - + context.SaveChanges(); + + //OneToMany + Console.WriteLine("Champions : "); + foreach (var champi in context.Champions.Include(a => a.skins)) + { + Console.WriteLine($"\t{champi.Name} : {champi.Bio}"); + foreach (var s in champi.skins) + { + Console.WriteLine($"\t\t{s.Name}"); + } + } + + Console.WriteLine(); + + Console.WriteLine("Skin :"); + foreach (var s in context.Skins) + { + Console.WriteLine($"\t{s.Name}: {s.Description} (Champion : {s.Champion.Name})"); + } + + + Console.WriteLine("\nAjout d'un Champion et 6 Skins...\n"); + + ChampionEntity captainMarvel = new ChampionEntity { Name = "Captain Marvel", Bio="Mais que fait un avenger ici ??", Icon="Icon.png"}; + SkinEntity[] skins = { new SkinEntity {Name = "La Fiesta", Champion = captainMarvel}, + new SkinEntity { Name = "Five Hundred Miles High", Champion = captainMarvel }, + new SkinEntity { Name = "Captain Marvel", Champion = captainMarvel }, + new SkinEntity { Name = "Time's Lie", Champion = captainMarvel }, + new SkinEntity { Name = "Lush Life", Champion = captainMarvel }, + new SkinEntity { Name = "Day Waves", Champion = captainMarvel } + }; + foreach (var s in skins) + { + captainMarvel.skins.Add(s); + } + + context.Add(captainMarvel); + context.SaveChanges(); + + } diff --git a/Sources/EntityFramework/SkillEntity.cs b/Sources/EntityFramework/SkillEntity.cs index d370410..505a427 100644 --- a/Sources/EntityFramework/SkillEntity.cs +++ b/Sources/EntityFramework/SkillEntity.cs @@ -10,42 +10,44 @@ namespace EntityFramework public class SkillEntity { - public SkillType Type { get; private set; } + public SkillType Type { get; set; } [Key] - public string Name - { - get => name; - private init - { - if (string.IsNullOrWhiteSpace(value)) - { - throw new ArgumentException("a Skill needs a name"); - } - name = value; - } - } - private readonly string name = null!; + public string Name { get; set; } + //public string Name + //{ + // get => name; + // private init + // { + // if (string.IsNullOrWhiteSpace(value)) + // { + // throw new ArgumentException("a Skill needs a name"); + // } + // name = value; + // } + //} + //private readonly string name = null!; - public string Description - { - get => description; - set - { - if (string.IsNullOrWhiteSpace(value)) - { - description = ""; - return; - } - description = value; - } - } - private string description = ""; + public string Description { get; set; } + //public string Description + //{ + // get => description; + // set + // { + // if (string.IsNullOrWhiteSpace(value)) + // { + // description = ""; + // return; + // } + // description = value; + // } + //} + //private string description = ""; - public SkillEntity(string Name, string Description, SkillType Type) { - this.name = Name; - this.Description = Description; - this.Type = Type; - } + //public SkillEntity(string Name, string Description, SkillType Type) { + // this.name = Name; + // this.Description = Description; + // this.Type = Type; + //} } } diff --git a/Sources/EntityFramework/SkinEntity.cs b/Sources/EntityFramework/SkinEntity.cs new file mode 100644 index 0000000..e9650b3 --- /dev/null +++ b/Sources/EntityFramework/SkinEntity.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EntityFramework +{ + public class SkinEntity //ONE TO MANY + { + + public string? Name { get; set; } + + public string? Description { get; set; } + + //public string Name + //{ + // get => name; + // private init + // { + // if (string.IsNullOrWhiteSpace(value)) + // { + // throw new ArgumentException("A skin must have a name"); + // } + // name = value; + // } + //} + //private readonly string name = null!; + + //public string Description + //{ + // get => description; + // set + // { + // if (string.IsNullOrWhiteSpace(value)) + // { + // description = ""; + // return; + // } + // description = value; + // } + //} + //private string description = ""; + + public string Icon { get; set; } = ""; + + + //public LargeImageEntity Image { get; set; } + public string? Image { get; set; } + + + public float Price { get; set; } + public ChampionEntity Champion { get; set; } + + + //public ChampionEntity Champion + //{ + // get => champion; + // private init + // { + // if (value == null) + // throw new ArgumentNullException("A skill can't have a null champion"); + // champion = value; + // } + //} + //private readonly ChampionEntity champion = null!; + + //public SkinEntity(string name, ChampionEntity champion, float price = 0.0f, string icon = "", string image = "", string description = "") + //{ + // Name = name; + // Champion = champion; + // //Champion.AddSkin(this); + // Price = price; + // Icon = icon; + // Image = new LargeImageEntity(image); + // Description = description; + //} + } +} diff --git a/Sources/EntityFramework/StubbedContext.cs b/Sources/EntityFramework/StubbedContext.cs new file mode 100644 index 0000000..833f0c7 --- /dev/null +++ b/Sources/EntityFramework/StubbedContext.cs @@ -0,0 +1,44 @@ +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EntityFramework +{ + public class StubbedContext : LoLDbContext + { + //protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + //{ + // optionsBuilder.EnableSensitiveDataLogging(); + //} + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + + ChampionEntity corichard = new ChampionEntity {Name="Corichard", Bio="biobiobiobio", Icon="/a/a/a/a"}; + ChampionEntity pintrand = new ChampionEntity {Name = "Pintrand", Bio = "mimimimimim", Icon = "/small.png" }; + + //ChampionEntity corichard = new ChampionEntity() { Name = "Corichard", Bio = "biobiobiobio", Icon = "/a/a/a/a", Image = new LargeImageEntity { Base64 = "base" } }; + //ChampionEntity pintrand = new ChampionEntity { Name = "Pintrand", Bio = "mimimimimim", Icon = "/small.png", Image = new LargeImageEntity { Base64 = "base" } }; + + modelBuilder.Entity().HasData(corichard, pintrand); + + modelBuilder.Entity().HasData(new { Name = "aaaa", ChampionEntityForeignKey = "Corichard", Description = "So What", Icon="/Icon.png", Price=10.0f }, + new { Name = "skin", ChampionEntityForeignKey = "Corichard", Description = "So What", Icon = "/Icon.png", Price = 10.0f }, + new { Name = "bo", ChampionEntityForeignKey = "Corichard", Description = "So What", Icon = "/Icon.png", Price = 10.0f }, + new { Name = "Joulie", ChampionEntityForeignKey = "Corichard", Description = "So What", Icon = "/Icon.png", Price = 10.0f }, + new { Name = "Radiance", ChampionEntityForeignKey = "Corichard", Description = "So What", Icon = "/Icon.png", Price = 10.0f }, + new { Name = "void", ChampionEntityForeignKey = "Corichard", Description = "So What", Icon = "/Icon.png", Price = 10.0f }, + new { Name = "Radiance", ChampionEntityForeignKey = "Pintrand", Description = "So What", Icon = "/Icon.png", Price = 10.0f }, + new { Name = "void", ChampionEntityForeignKey = "Pintrand", Description = "So What", Icon = "/Icon.png", Price = 10.0f }, + new { Name = "DarkTheme", ChampionEntityForeignKey = "Pintrand", Description = "So What", Icon = "/Icon.png", Price = 10.0f }, + new { Name = "gold", ChampionEntityForeignKey = "Pintrand", Description = "So What", Icon = "/Icon.png", Price = 10.0f }, + new { Name = "ruby", ChampionEntityForeignKey = "Pintrand", Description = "So What", Icon = "/Icon.png", Price = 10.0f } + ); + } + + } +} diff --git a/Sources/EntityFramework/champion.db b/Sources/EntityFramework/champion.db index b0ff12d..d4cefaf 100644 Binary files a/Sources/EntityFramework/champion.db and b/Sources/EntityFramework/champion.db differ