🗃️ Add TurnEntity and implement many-to-many

pull/191/head
Alexis Drai 3 years ago
parent bf22c44740
commit 0a01b402c0

@ -1,6 +1,7 @@
using Data.EF.Dice;
using Data.EF.Dice.Faces;
using Data.EF.Games;
using Data.EF.Joins;
using Data.EF.Players;
using Microsoft.EntityFrameworkCore;
using Model.Games;
@ -13,12 +14,13 @@ namespace Data.EF
public virtual Task<MasterOfCeremonies> LoadApp() { throw new NotImplementedException(); }
public DbSet<PlayerEntity> PlayerEntity { get; set; }
public DbSet<NumberDieEntity> NumberDice { get; set; }
public DbSet<NumberFaceEntity> NumberFaces { get; set; }
public DbSet<ImageDieEntity> ImageDice { get; set; }
public DbSet<ImageFaceEntity> ImageFaces { get; set; }
public DbSet<ColorDieEntity> ColorDice { get; set; }
public DbSet<ColorFaceEntity> ColorFaces { get; set; }
public DbSet<TurnEntity> TurnEntity { get; set; }
public DbSet<NumberDieEntity> NumberDieEntity { get; set; }
public DbSet<NumberFaceEntity> NumberFaceEntity { get; set; }
public DbSet<ImageDieEntity> ImageDieEntity { get; set; }
public DbSet<ImageFaceEntity> ImageFaceEntity { get; set; }
public DbSet<ColorDieEntity> ColorDieEntity { get; set; }
public DbSet<ColorFaceEntity> ColorFaceEntity { get; set; }
public DiceAppDbContext() { }
@ -29,5 +31,52 @@ namespace Data.EF
{
if (!optionsBuilder.IsConfigured) optionsBuilder.UseSqlite("Data Source=EFDice.DiceApp.db").EnableSensitiveDataLogging();
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// thanks to https://learn.microsoft.com/en-us/ef/core/modeling/relationships?tabs=fluent-api%2Cfluent-api-simple-key%2Csimple-key#join-entity-type-configuration
// many to many TurnEntity <-> FaceEntity
modelBuilder.Entity<FaceEntity>()
.HasMany(face => face.Turns)
.WithMany(turn => turn.Faces)
.UsingEntity<FaceTurn>(
join => join
// FaceTurn --> TurnEntity
.HasOne(faceturn => faceturn.TurnEntity)
.WithMany(turn => turn.FaceTurns)
.HasForeignKey(faceturn => faceturn.TurnEntityID),
join => join
// FaceTurn --> FaceEntity
.HasOne(faceturn => faceturn.FaceEntity)
.WithMany(face => face.FaceTurns)
.HasForeignKey(faceturn => faceturn.FaceEntityID),
// FaceTurn.PK = (ID1, ID2)
join => join.HasKey(faceturn => new { faceturn.FaceEntityID, faceturn.TurnEntityID })
);
// many to many TurnEntity <-> DieEntity
modelBuilder.Entity<DieEntity>()
.HasMany(die => die.Turns)
.WithMany(turn => turn.Dice)
.UsingEntity<DieTurn>(
join => join
// DieTurn --> TurnEntity
.HasOne(dieturn => dieturn.TurnEntity)
.WithMany(turn => turn.DieTurns)
.HasForeignKey(dieturn => dieturn.TurnEntityID),
join => join
// DieTurn --> DieEntity
.HasOne(dieturn => dieturn.DieEntity)
.WithMany(die => die.DieTurns)
.HasForeignKey(dieturn => dieturn.DieEntityID),
// DieTurn.PK = (ID1, ID2)
join => join.HasKey(dieturn => new { dieturn.DieEntityID, dieturn.TurnEntityID })
);
}
}
}

@ -1,4 +1,8 @@
using Data.EF.Players;
using Data.EF.Dice;
using Data.EF.Dice.Faces;
using Data.EF.Games;
using Data.EF.Joins;
using Data.EF.Players;
using Microsoft.EntityFrameworkCore;
using Model.Games;
using System.Linq.Expressions;
@ -20,12 +24,182 @@ namespace Data.EF
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<PlayerEntity>().HasData(
new PlayerEntity { ID = Guid.NewGuid(), Name = "Alice" }, // some tests depend on this name
new PlayerEntity { ID = new("6e856818-92f1-4d7d-b35c-f9c6687ef8e1"), Name = "Bob" }, // some tests depend on this name and this ID
new PlayerEntity { ID = Guid.NewGuid(), Name = "Clyde" }, // some tests depend on this name
new PlayerEntity { ID = Guid.NewGuid(), Name = "Dahlia" } // some tests depend on this name
);
Guid playerID_1 = Guid.NewGuid();
Guid playerID_2 = new("6e856818-92f1-4d7d-b35c-f9c6687ef8e1");
Guid playerID_3 = Guid.NewGuid();
Guid playerID_4 = Guid.NewGuid();
PlayerEntity player_1 = new() { ID = playerID_1, Name = "Alice" };
PlayerEntity player_2 = new() { ID = playerID_2, Name = "Bob" };
PlayerEntity player_3 = new() { ID = playerID_3, Name = "Clyde" };
PlayerEntity player_4 = new() { ID = playerID_4, Name = "Dahlia" };
Guid turnID_1 = Guid.NewGuid();
Guid turnID_2 = Guid.NewGuid();
TurnEntity turn_1 = new()
{
ID = turnID_1,
When = new DateTime(2017, 1, 6, 17, 30, 0, DateTimeKind.Utc),
PlayerEntityID = playerID_1
};
TurnEntity turn_2 = new()
{
ID = turnID_2,
When = DateTime.UtcNow,
PlayerEntityID = playerID_2
};
Guid dieID_1 = Guid.NewGuid();
Guid dieID_2 = Guid.NewGuid();
Guid dieID_3 = Guid.NewGuid();
NumberDieEntity die_1 = new() { ID = dieID_1 };
ImageDieEntity die_2 = new() { ID = dieID_2 };
ColorDieEntity die_3 = new() { ID = dieID_3 };
Guid faceID_1 = Guid.NewGuid();
Guid faceID_2 = Guid.NewGuid();
Guid faceID_3 = Guid.NewGuid();
Guid faceID_4 = Guid.NewGuid();
Guid faceID_5 = Guid.NewGuid();
Guid faceID_6 = Guid.NewGuid();
NumberFaceEntity face_1 = new()
{
ID = faceID_1,
Value = 1,
NumberDieEntityID = dieID_1
};
NumberFaceEntity face_2 = new()
{
ID = faceID_2,
Value = 2,
NumberDieEntityID = dieID_1
};
ImageFaceEntity face_3 = new()
{
ID = faceID_3,
Value = "https://1",
ImageDieEntityID = dieID_2
};
ImageFaceEntity face_4 = new()
{
ID = faceID_4,
Value = "https://2",
ImageDieEntityID = dieID_2
};
ColorFaceEntity face_5 = new()
{
ID = faceID_5,
A = 255,
R = 255,
G = 0,
B = 0,
ColorDieEntityID = dieID_3
};
ColorFaceEntity face_6 = new()
{
ID = faceID_6,
A = 255,
R = 0,
G = 255,
B = 0,
ColorDieEntityID = dieID_3
};
modelBuilder.Entity<PlayerEntity>().HasData(player_1, player_2, player_3, player_4);
modelBuilder.Entity<TurnEntity>().HasData(turn_1, turn_2);
modelBuilder.Entity<NumberDieEntity>().HasData(die_1);
modelBuilder.Entity<NumberFaceEntity>().HasData(face_1, face_2);
modelBuilder.Entity<ImageDieEntity>().HasData(die_2);
modelBuilder.Entity<ImageFaceEntity>().HasData(face_3, face_4);
modelBuilder.Entity<ColorDieEntity>().HasData(die_3);
modelBuilder.Entity<ColorFaceEntity>().HasData(face_5, face_6);
// die 1 die 2 die 3
// turn 1 : num->2, img->https://2, clr->red
// turn 2 : num->1, clr->green
modelBuilder
.Entity<TurnEntity>()
.HasMany(turn => turn.Faces)
.WithMany(face => face.Turns)
.UsingEntity<FaceTurn>(
join => join.HasData(
new
{
TurnEntityID = turnID_1,
FaceEntityID = faceID_2
},
new
{
TurnEntityID = turnID_1,
FaceEntityID = faceID_4
},
new
{
TurnEntityID = turnID_1,
FaceEntityID = faceID_5
},
new
{
TurnEntityID = turnID_2,
FaceEntityID = faceID_1
},
new
{
TurnEntityID = turnID_2,
FaceEntityID = faceID_6
}
)
);
modelBuilder
.Entity<TurnEntity>()
.HasMany(turn => turn.Dice)
.WithMany(die => die.Turns)
.UsingEntity<DieTurn>(
join => join.HasData(
new
{
TurnEntityID = turnID_1,
DieEntityID = dieID_1
},
new
{
TurnEntityID = turnID_1,
DieEntityID = dieID_2
},
new
{
TurnEntityID = turnID_1,
DieEntityID = dieID_3
},
new
{
TurnEntityID = turnID_2,
DieEntityID = dieID_1
},
new
{
TurnEntityID = turnID_2,
DieEntityID = dieID_3
}
)
);
}
}
}

@ -1,5 +1,6 @@
using Data.EF.Dice;
using Data.EF.Dice.Faces;
using Data.EF.Joins;
using Data.EF.Players;
namespace Data.EF.Games
@ -9,13 +10,10 @@ namespace Data.EF.Games
public Guid ID { get; set; }
public DateTime When { get; set; }
public PlayerEntity Player { get; set; }
public List<NumberDieEntity> NumberDice { get; set; }
public List<NumberFaceEntity> NumberFaces { get; set; }
public List<ImageDieEntity> ImageDice { get; set; }
public List<ImageFaceEntity> ImageFaces { get; set; }
public List<ColorDieEntity> ColorDice { get; set; }
public List<ColorFaceEntity> ColorFaces { get; set; }
public Guid PlayerEntityID { get; set; }
public ICollection<DieEntity> Dice { get; set; } // many to many
public List<DieTurn> DieTurns { get; set; }
public ICollection<FaceEntity> Faces { get; set; } // many to many
public List<FaceTurn> FaceTurns { get; set; }
}
}

@ -10,27 +10,59 @@ namespace Data.EF.Games
public static class TurnExtensions
{
private static (List<Die>, List<Face>) ToModels(ICollection<DieEntity> diceEntities, ICollection<FaceEntity> faceEntities)
{
List<Die> dice = new();
List<Face> faces = new();
foreach (DieEntity dieEntity in diceEntities)
{
if (dieEntity.GetType() == typeof(NumberDieEntity))
{
dice.Add((dieEntity as NumberDieEntity).ToModel());
}
if (dieEntity.GetType() == typeof(ColorDieEntity))
{
dice.Add((dieEntity as ColorDieEntity).ToModel());
}
if (dieEntity.GetType() == typeof(ImageDieEntity))
{
dice.Add((dieEntity as ImageDieEntity).ToModel());
}
}
foreach (FaceEntity faceEntity in faceEntities)
{
if (faceEntity.GetType() == typeof(NumberFaceEntity))
{
faces.Add((faceEntity as NumberFaceEntity).ToModel());
}
if (faceEntity.GetType() == typeof(ColorFaceEntity))
{
faces.Add((faceEntity as ColorFaceEntity).ToModel());
}
if (faceEntity.GetType() == typeof(ImageFaceEntity))
{
faces.Add((faceEntity as ImageFaceEntity).ToModel());
}
}
return (dice, faces);
}
public static Turn ToModel(this TurnEntity entity)
{
Dictionary<Die, Face> DiceNFaces = new();
DiceNFaces = Utils.Enumerables.FeedListsToDict(
DiceNFaces,
entity.ColorDice.ToModels() as List<Die>,
entity.ColorFaces.ToModels() as List<Face>
);
List<Die> keysList;
List<Face> valuesList;
DiceNFaces = Utils.Enumerables.FeedListsToDict(
DiceNFaces,
entity.NumberDice.ToModels() as List<Die>,
entity.NumberFaces.ToModels() as List<Face>
);
(keysList, valuesList) = ToModels(entity.Dice, entity.Faces);
DiceNFaces = Utils.Enumerables.FeedListsToDict(
DiceNFaces,
entity.ImageDice.ToModels() as List<Die>,
entity.ImageFaces.ToModels() as List<Face>
keysList,
valuesList
);
return Turn.CreateWithSpecifiedTime(
@ -48,29 +80,25 @@ namespace Data.EF.Games
public static TurnEntity ToEntity(this Turn model)
{
List<NumberDieEntity> NumberDiceEntities = new();
List<ColorDieEntity> ColorDiceEntities = new();
List<ImageDieEntity> ImageDiceEntities = new();
List<NumberFaceEntity> NumberFaceEntities = new();
List<ColorFaceEntity> ColorFaceEntities = new();
List<ImageFaceEntity> ImageFaceEntities = new();
List<DieEntity> DiceEntities = new();
List<FaceEntity> FaceEntities = new();
foreach (KeyValuePair<Die, Face> kvp in model.DiceNFaces)
{
if (kvp.Key.GetType() == typeof(NumberDie))
{
NumberDiceEntities.Add((kvp.Key as NumberDie).ToEntity());
NumberFaceEntities.Add((kvp.Value as NumberFace).ToEntity());
DiceEntities.Add((kvp.Key as NumberDie).ToEntity());
FaceEntities.Add((kvp.Value as NumberFace).ToEntity());
}
if (kvp.Key.GetType() == typeof(ImageDie))
{
ImageDiceEntities.Add((kvp.Key as ImageDie).ToEntity());
ImageFaceEntities.Add((kvp.Value as ImageFace).ToEntity());
DiceEntities.Add((kvp.Key as ImageDie).ToEntity());
FaceEntities.Add((kvp.Value as ImageFace).ToEntity());
}
if (kvp.Key.GetType() == typeof(ColorDie))
{
ColorDiceEntities.Add((kvp.Key as ColorDie).ToEntity());
ColorFaceEntities.Add((kvp.Value as ColorFace).ToEntity());
DiceEntities.Add((kvp.Key as ColorDie).ToEntity());
FaceEntities.Add((kvp.Value as ColorFace).ToEntity());
}
}
@ -78,12 +106,8 @@ namespace Data.EF.Games
{
When = model.When,
Player = model.Player.ToEntity(),
NumberDice = NumberDiceEntities,
NumberFaces = NumberFaceEntities,
ColorDice = ColorDiceEntities,
ColorFaces = ColorFaceEntities,
ImageDice = ImageDiceEntities,
ImageFaces = ImageFaceEntities
//Dice = DiceEntities,
Faces = FaceEntities
};
}

@ -0,0 +1,15 @@
using Data.EF.Dice;
using Data.EF.Dice.Faces;
using Data.EF.Games;
namespace Data.EF.Joins
{
public class DieTurn
{
public Guid DieEntityID { get; set; }
public DieEntity DieEntity { get; set; }
public Guid TurnEntityID { get; set; }
public TurnEntity TurnEntity { get; set; }
}
}

@ -0,0 +1,19 @@
using Data.EF.Dice.Faces;
using Data.EF.Games;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Data.EF.Joins
{
public class FaceTurn
{
public Guid FaceEntityID { get; set; }
public FaceEntity FaceEntity { get; set; }
public Guid TurnEntityID { get; set; }
public TurnEntity TurnEntity { get; set; }
}
}
Loading…
Cancel
Save