diff --git a/Common.Library/Interfaces/IRepository.cs b/Common.Library/Interfaces/IRepository.cs index a2e77d0..76d01c6 100644 --- a/Common.Library/Interfaces/IRepository.cs +++ b/Common.Library/Interfaces/IRepository.cs @@ -1,10 +1,9 @@ -using System.Collections.ObjectModel; - -namespace Common.Library; +namespace Common.Library; public interface IRepository { - Task> Get(); - TEntity Get(int id); - bool Save(TEntity entity); + Task> Get(); + Task Get(int id); + Task Save(TEntity entity); + bool Delete(TEntity entity); } diff --git a/GreadyPoang.DataLayer/DataClasses/GamePointRepository.cs b/GreadyPoang.DataLayer/DataClasses/GamePointRepository.cs new file mode 100644 index 0000000..574a401 --- /dev/null +++ b/GreadyPoang.DataLayer/DataClasses/GamePointRepository.cs @@ -0,0 +1,67 @@ +using Common.Library; +using GreadyPoang.DataLayer.Database; +using GreadyPoang.EntityLayer; +using Microsoft.EntityFrameworkCore; + +namespace GreadyPoang.DataLayer; + +public class GamePointRepository : IRepository +{ + private readonly DataContext _dataContext; + + public GamePointRepository(DataContext dataContext) + { + _dataContext = dataContext; + } + public async Task> Get() + { + return await _dataContext.GamePoints.ToListAsync(); + } + public async Task Get(int id) + { + return await _dataContext.GamePoints.FindAsync(id); + } + public async Task Save(GamePoint entity) + { + var res = false; + if ((entity.GameHeatRegNr == 0) + || (entity.GameRegPoints == 0)) + { + return res; // Validation failed + } + + if (entity.GamePointId == 0) + { + _dataContext.GamePoints.Add(entity); + await _dataContext.SaveChangesAsync(); + res = true; + } + else + { + _dataContext.GamePoints.Update(entity); + await _dataContext.SaveChangesAsync(); + res = true; + } + return res; + } + + public bool Delete(GamePoint entity) + { + var res = false; + try + { + _dataContext.GamePoints.Remove(entity); + _dataContext.SaveChanges(); + res = true; + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine($"Error deleting participant: {ex.Message}"); + res = false; + } + return res; + } + + + +} diff --git a/GreadyPoang.DataLayer/DataClasses/ParticipantRepository.cs b/GreadyPoang.DataLayer/DataClasses/ParticipantRepository.cs index 0c67db8..311153b 100644 --- a/GreadyPoang.DataLayer/DataClasses/ParticipantRepository.cs +++ b/GreadyPoang.DataLayer/DataClasses/ParticipantRepository.cs @@ -1,88 +1,65 @@ using Common.Library; +using GreadyPoang.DataLayer.Database; using GreadyPoang.EntityLayer; -using System.Collections.ObjectModel; +using Microsoft.EntityFrameworkCore; namespace GreadyPoang.DataLayer; public class ParticipantRepository : IRepository { - private readonly LocalDbService _dbService; - private ObservableCollection lager; + private readonly DataContext _dataContext; - public ParticipantRepository(LocalDbService dbService) + public ParticipantRepository(DataContext dataContext) { - if (lager == null || lager.Count == 0) - { - lager = new ObservableCollection(); - } - _dbService = dbService; + _dataContext = dataContext; } - - #region Get Method - public async Task> Get() + public async Task> Get() { - // This method should return a collection of Participant objects. - // For now, returning an empty collection. - List result = await _dbService.GetParticipantsAsync(); - - - if (result != null) + return await _dataContext.Participants.ToListAsync(); + } + public async Task Get(int id) + { + // Fix: Use FindAsync with key value array, not a predicate + return await _dataContext.Participants.FindAsync(id); + } + public async Task Save(Participant entity) + { + var res = false; + if (string.IsNullOrEmpty(entity.FirstName) + || string.IsNullOrEmpty(entity.LastName)) { - foreach (var participant in result) - { - if (!lager.Any(p => p.ParticipantId == participant.ParticipantId)) - { - lager.Add(participant); - } - } + return res; // Validation failed } - return lager; - } - - public Participant? Get(int id) - { - Participant? participant = null; // Initialize the variable to avoid CS0165 - _dbService.GetParticipantAsync(id).ContinueWith(task => + if (entity.ParticipantId == 0) { - if (task.Exception == null) - { - participant = task.Result; - if (participant != null) - { - System.Diagnostics.Debug.WriteLine($"Fetched Participant by ID: {participant.ParticipantId}, {participant.FirstName}, {participant.LastName}, {participant.Email}"); - } - else - { - System.Diagnostics.Debug.WriteLine($"No Participant found with ID: {id}"); - } - } - else - { - // Handle exceptions as needed - System.Diagnostics.Debug.WriteLine($"Error fetching participant by ID: {task.Exception.Message}"); - } - }).Wait(); + _dataContext.Participants.Add(entity); + await _dataContext.SaveChangesAsync(); + res = true; + } + else + { + _dataContext.Participants.Update(entity); + await _dataContext.SaveChangesAsync(); + res = true; + } + return res; - return participant; } - #endregion - - public bool Save(Participant entity) + public bool Delete(Participant entity) { - var output = false; + var res = false; try { - _dbService.SaveParticipantAsync(entity).Wait(); - lager.Add(entity); - output = true; + _dataContext.Participants.Remove(entity); + _dataContext.SaveChanges(); + res = true; } catch (Exception ex) { - System.Diagnostics.Debug.WriteLine($"Error saving participants: {ex.Message}"); + System.Diagnostics.Debug.WriteLine($"Error deleting participant: {ex.Message}"); + res = false; } - - return output; - + return res; } } diff --git a/GreadyPoang.DataLayer/Database/DataContext.cs b/GreadyPoang.DataLayer/Database/DataContext.cs index 3222408..9793b4c 100644 --- a/GreadyPoang.DataLayer/Database/DataContext.cs +++ b/GreadyPoang.DataLayer/Database/DataContext.cs @@ -1,25 +1,32 @@ using GreadyPoang.EntityLayer; using Microsoft.EntityFrameworkCore; -namespace GreadyPoang.DataLayer.Database +namespace GreadyPoang.DataLayer.Database; + +public class DataContext : DbContext { - public class DataContext : DbContext + public DataContext(DbContextOptions options) : base(options) { - public DataContext(DbContextOptions options) : base(options) - { - } - //public DbSet Users => Set(); - public DbSet Participants { get; set; } + } + //public DbSet Users => Set(); + public DbSet Participants { get; set; } + public DbSet GamePoints { get; set; } - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - base.OnModelCreating(modelBuilder); - modelBuilder.Entity().HasData( - new Participant { ParticipantId = 1, FirstName = "John", LastName = "Doe", Email = "John.Doe@gmail.com" }, - new Participant { ParticipantId = 2, FirstName = "Jane", LastName = "Black", Email = "jb@gmail.com" }, - new Participant { ParticipantId = 3, FirstName = "Mary", LastName = "White", Email = "mw@gmail.com" } - ); - } + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + modelBuilder.Entity().HasData( + new Participant { ParticipantId = 1, FirstName = "John", LastName = "Doe", Email = "John.Doe@gmail.com" }, + new Participant { ParticipantId = 2, FirstName = "Jane", LastName = "Black", Email = "jb@gmail.com" }, + new Participant { ParticipantId = 3, FirstName = "Mary", LastName = "White", Email = "mw@gmail.com" } + ); + modelBuilder.Entity().HasData( + new GamePoint { GamePointId = 1, ParticipantId = 1, GameHeatId = 0, GameDate = new DateTime(2025, 10, 15, 20, 10, 15), GameHeatRegNr = 1, GameRegPoints = 1050 }, + new GamePoint { GamePointId = 2, ParticipantId = 1, GameHeatId = 0, GameDate = new DateTime(2025, 10, 15, 20, 15, 15), GameHeatRegNr = 3, GameRegPoints = 350 }, + new GamePoint { GamePointId = 3, ParticipantId = 3, GameHeatId = 0, GameDate = new DateTime(2025, 10, 15, 20, 12, 15), GameHeatRegNr = 2, GameRegPoints = 1000 }, + new GamePoint { GamePointId = 4, ParticipantId = 3, GameHeatId = 0, GameDate = new DateTime(2025, 10, 15, 20, 20, 15), GameHeatRegNr = 4, GameRegPoints = 400 } + ); } } + diff --git a/GreadyPoang.DataLayer/GreadyPoang.DataLayer.csproj b/GreadyPoang.DataLayer/GreadyPoang.DataLayer.csproj index f1393fc..1dbefd6 100644 --- a/GreadyPoang.DataLayer/GreadyPoang.DataLayer.csproj +++ b/GreadyPoang.DataLayer/GreadyPoang.DataLayer.csproj @@ -7,6 +7,14 @@ + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/GreadyPoang.DataLayer/Migrations/20250901152226_initialCreate.Designer.cs b/GreadyPoang.DataLayer/Migrations/20250901152226_initialCreate.Designer.cs new file mode 100644 index 0000000..680fd3a --- /dev/null +++ b/GreadyPoang.DataLayer/Migrations/20250901152226_initialCreate.Designer.cs @@ -0,0 +1,70 @@ +// +using GreadyPoang.DataLayer.Database; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace GreadyPoang.DataLayer.Migrations +{ + [DbContext(typeof(DataContext))] + [Migration("20250901152226_initialCreate")] + partial class initialCreate + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "9.0.8"); + + modelBuilder.Entity("GreadyPoang.EntityLayer.Participant", b => + { + b.Property("ParticipantId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Email") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("LastName") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("ParticipantId"); + + b.ToTable("Participants"); + + b.HasData( + new + { + ParticipantId = 1, + Email = "John.Doe@gmail.com", + FirstName = "John", + LastName = "Doe" + }, + new + { + ParticipantId = 2, + Email = "jb@gmail.com", + FirstName = "Jane", + LastName = "Black" + }, + new + { + ParticipantId = 3, + Email = "mw@gmail.com", + FirstName = "Mary", + LastName = "White" + }); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/GreadyPoang.DataLayer/Migrations/20250901152226_initialCreate.cs b/GreadyPoang.DataLayer/Migrations/20250901152226_initialCreate.cs new file mode 100644 index 0000000..72e7638 --- /dev/null +++ b/GreadyPoang.DataLayer/Migrations/20250901152226_initialCreate.cs @@ -0,0 +1,48 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional + +namespace GreadyPoang.DataLayer.Migrations +{ + /// + public partial class initialCreate : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Participants", + columns: table => new + { + ParticipantId = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + FirstName = table.Column(type: "TEXT", nullable: false), + LastName = table.Column(type: "TEXT", nullable: false), + Email = table.Column(type: "TEXT", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Participants", x => x.ParticipantId); + }); + + migrationBuilder.InsertData( + table: "Participants", + columns: new[] { "ParticipantId", "Email", "FirstName", "LastName" }, + values: new object[,] + { + { 1, "John.Doe@gmail.com", "John", "Doe" }, + { 2, "jb@gmail.com", "Jane", "Black" }, + { 3, "mw@gmail.com", "Mary", "White" } + }); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Participants"); + } + } +} diff --git a/GreadyPoang.DataLayer/Migrations/20250902115700_GamePointsTable.Designer.cs b/GreadyPoang.DataLayer/Migrations/20250902115700_GamePointsTable.Designer.cs new file mode 100644 index 0000000..05d8650 --- /dev/null +++ b/GreadyPoang.DataLayer/Migrations/20250902115700_GamePointsTable.Designer.cs @@ -0,0 +1,135 @@ +// +using System; +using GreadyPoang.DataLayer.Database; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace GreadyPoang.DataLayer.Migrations +{ + [DbContext(typeof(DataContext))] + [Migration("20250902115700_GamePointsTable")] + partial class GamePointsTable + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "9.0.8"); + + modelBuilder.Entity("GreadyPoang.EntityLayer.GamePoint", b => + { + b.Property("GamePointId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("GameDate") + .HasColumnType("TEXT"); + + b.Property("GameHeatId") + .HasColumnType("INTEGER"); + + b.Property("GameHeatRegNr") + .HasColumnType("INTEGER"); + + b.Property("GameRegPoints") + .HasColumnType("INTEGER"); + + b.Property("ParticipantId") + .HasColumnType("INTEGER"); + + b.HasKey("GamePointId"); + + b.ToTable("GamePoints"); + + b.HasData( + new + { + GamePointId = 1, + GameDate = new DateTime(2025, 9, 2, 13, 56, 59, 539, DateTimeKind.Local).AddTicks(8341), + GameHeatId = 0, + GameHeatRegNr = 1, + GameRegPoints = 1050, + ParticipantId = 1 + }, + new + { + GamePointId = 2, + GameDate = new DateTime(2025, 9, 2, 13, 56, 59, 539, DateTimeKind.Local).AddTicks(8923), + GameHeatId = 0, + GameHeatRegNr = 3, + GameRegPoints = 350, + ParticipantId = 1 + }, + new + { + GamePointId = 3, + GameDate = new DateTime(2025, 9, 2, 13, 56, 59, 539, DateTimeKind.Local).AddTicks(8927), + GameHeatId = 0, + GameHeatRegNr = 2, + GameRegPoints = 1000, + ParticipantId = 3 + }, + new + { + GamePointId = 4, + GameDate = new DateTime(2025, 9, 2, 13, 56, 59, 539, DateTimeKind.Local).AddTicks(8929), + GameHeatId = 0, + GameHeatRegNr = 4, + GameRegPoints = 400, + ParticipantId = 3 + }); + }); + + modelBuilder.Entity("GreadyPoang.EntityLayer.Participant", b => + { + b.Property("ParticipantId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Email") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("LastName") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("ParticipantId"); + + b.ToTable("Participants"); + + b.HasData( + new + { + ParticipantId = 1, + Email = "John.Doe@gmail.com", + FirstName = "John", + LastName = "Doe" + }, + new + { + ParticipantId = 2, + Email = "jb@gmail.com", + FirstName = "Jane", + LastName = "Black" + }, + new + { + ParticipantId = 3, + Email = "mw@gmail.com", + FirstName = "Mary", + LastName = "White" + }); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/GreadyPoang.DataLayer/Migrations/20250902115700_GamePointsTable.cs b/GreadyPoang.DataLayer/Migrations/20250902115700_GamePointsTable.cs new file mode 100644 index 0000000..e5f346f --- /dev/null +++ b/GreadyPoang.DataLayer/Migrations/20250902115700_GamePointsTable.cs @@ -0,0 +1,52 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional + +namespace GreadyPoang.DataLayer.Migrations +{ + /// + public partial class GamePointsTable : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "GamePoints", + columns: table => new + { + GamePointId = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + ParticipantId = table.Column(type: "INTEGER", nullable: false), + GameHeatId = table.Column(type: "INTEGER", nullable: false), + GameDate = table.Column(type: "TEXT", nullable: false), + GameHeatRegNr = table.Column(type: "INTEGER", nullable: false), + GameRegPoints = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_GamePoints", x => x.GamePointId); + }); + + migrationBuilder.InsertData( + table: "GamePoints", + columns: new[] { "GamePointId", "GameDate", "GameHeatId", "GameHeatRegNr", "GameRegPoints", "ParticipantId" }, + values: new object[,] + { + { 1, new DateTime(2025, 9, 2, 13, 56, 59, 539, DateTimeKind.Local).AddTicks(8341), 0, 1, 1050, 1 }, + { 2, new DateTime(2025, 9, 2, 13, 56, 59, 539, DateTimeKind.Local).AddTicks(8923), 0, 3, 350, 1 }, + { 3, new DateTime(2025, 9, 2, 13, 56, 59, 539, DateTimeKind.Local).AddTicks(8927), 0, 2, 1000, 3 }, + { 4, new DateTime(2025, 9, 2, 13, 56, 59, 539, DateTimeKind.Local).AddTicks(8929), 0, 4, 400, 3 } + }); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "GamePoints"); + } + } +} diff --git a/GreadyPoang.DataLayer/Migrations/20250902120934_GamePointsTableStaticSeed.Designer.cs b/GreadyPoang.DataLayer/Migrations/20250902120934_GamePointsTableStaticSeed.Designer.cs new file mode 100644 index 0000000..2436097 --- /dev/null +++ b/GreadyPoang.DataLayer/Migrations/20250902120934_GamePointsTableStaticSeed.Designer.cs @@ -0,0 +1,135 @@ +// +using System; +using GreadyPoang.DataLayer.Database; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace GreadyPoang.DataLayer.Migrations +{ + [DbContext(typeof(DataContext))] + [Migration("20250902120934_GamePointsTableStaticSeed")] + partial class GamePointsTableStaticSeed + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "9.0.8"); + + modelBuilder.Entity("GreadyPoang.EntityLayer.GamePoint", b => + { + b.Property("GamePointId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("GameDate") + .HasColumnType("TEXT"); + + b.Property("GameHeatId") + .HasColumnType("INTEGER"); + + b.Property("GameHeatRegNr") + .HasColumnType("INTEGER"); + + b.Property("GameRegPoints") + .HasColumnType("INTEGER"); + + b.Property("ParticipantId") + .HasColumnType("INTEGER"); + + b.HasKey("GamePointId"); + + b.ToTable("GamePoints"); + + b.HasData( + new + { + GamePointId = 1, + GameDate = new DateTime(2025, 9, 2, 14, 9, 34, 269, DateTimeKind.Local).AddTicks(5394), + GameHeatId = 0, + GameHeatRegNr = 1, + GameRegPoints = 1050, + ParticipantId = 1 + }, + new + { + GamePointId = 2, + GameDate = new DateTime(2025, 9, 2, 14, 9, 34, 269, DateTimeKind.Local).AddTicks(6081), + GameHeatId = 0, + GameHeatRegNr = 3, + GameRegPoints = 350, + ParticipantId = 1 + }, + new + { + GamePointId = 3, + GameDate = new DateTime(2025, 9, 2, 14, 9, 34, 269, DateTimeKind.Local).AddTicks(6085), + GameHeatId = 0, + GameHeatRegNr = 2, + GameRegPoints = 1000, + ParticipantId = 3 + }, + new + { + GamePointId = 4, + GameDate = new DateTime(2025, 9, 2, 14, 9, 34, 269, DateTimeKind.Local).AddTicks(6088), + GameHeatId = 0, + GameHeatRegNr = 4, + GameRegPoints = 400, + ParticipantId = 3 + }); + }); + + modelBuilder.Entity("GreadyPoang.EntityLayer.Participant", b => + { + b.Property("ParticipantId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Email") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("LastName") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("ParticipantId"); + + b.ToTable("Participants"); + + b.HasData( + new + { + ParticipantId = 1, + Email = "John.Doe@gmail.com", + FirstName = "John", + LastName = "Doe" + }, + new + { + ParticipantId = 2, + Email = "jb@gmail.com", + FirstName = "Jane", + LastName = "Black" + }, + new + { + ParticipantId = 3, + Email = "mw@gmail.com", + FirstName = "Mary", + LastName = "White" + }); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/GreadyPoang.DataLayer/Migrations/20250902120934_GamePointsTableStaticSeed.cs b/GreadyPoang.DataLayer/Migrations/20250902120934_GamePointsTableStaticSeed.cs new file mode 100644 index 0000000..133961e --- /dev/null +++ b/GreadyPoang.DataLayer/Migrations/20250902120934_GamePointsTableStaticSeed.cs @@ -0,0 +1,75 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace GreadyPoang.DataLayer.Migrations +{ + /// + public partial class GamePointsTableStaticSeed : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.UpdateData( + table: "GamePoints", + keyColumn: "GamePointId", + keyValue: 1, + column: "GameDate", + value: new DateTime(2025, 9, 2, 14, 9, 34, 269, DateTimeKind.Local).AddTicks(5394)); + + migrationBuilder.UpdateData( + table: "GamePoints", + keyColumn: "GamePointId", + keyValue: 2, + column: "GameDate", + value: new DateTime(2025, 9, 2, 14, 9, 34, 269, DateTimeKind.Local).AddTicks(6081)); + + migrationBuilder.UpdateData( + table: "GamePoints", + keyColumn: "GamePointId", + keyValue: 3, + column: "GameDate", + value: new DateTime(2025, 9, 2, 14, 9, 34, 269, DateTimeKind.Local).AddTicks(6085)); + + migrationBuilder.UpdateData( + table: "GamePoints", + keyColumn: "GamePointId", + keyValue: 4, + column: "GameDate", + value: new DateTime(2025, 9, 2, 14, 9, 34, 269, DateTimeKind.Local).AddTicks(6088)); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.UpdateData( + table: "GamePoints", + keyColumn: "GamePointId", + keyValue: 1, + column: "GameDate", + value: new DateTime(2025, 9, 2, 13, 56, 59, 539, DateTimeKind.Local).AddTicks(8341)); + + migrationBuilder.UpdateData( + table: "GamePoints", + keyColumn: "GamePointId", + keyValue: 2, + column: "GameDate", + value: new DateTime(2025, 9, 2, 13, 56, 59, 539, DateTimeKind.Local).AddTicks(8923)); + + migrationBuilder.UpdateData( + table: "GamePoints", + keyColumn: "GamePointId", + keyValue: 3, + column: "GameDate", + value: new DateTime(2025, 9, 2, 13, 56, 59, 539, DateTimeKind.Local).AddTicks(8927)); + + migrationBuilder.UpdateData( + table: "GamePoints", + keyColumn: "GamePointId", + keyValue: 4, + column: "GameDate", + value: new DateTime(2025, 9, 2, 13, 56, 59, 539, DateTimeKind.Local).AddTicks(8929)); + } + } +} diff --git a/GreadyPoang.DataLayer/Migrations/20250902122130_FixDateTimeSeed.Designer.cs b/GreadyPoang.DataLayer/Migrations/20250902122130_FixDateTimeSeed.Designer.cs new file mode 100644 index 0000000..046bce8 --- /dev/null +++ b/GreadyPoang.DataLayer/Migrations/20250902122130_FixDateTimeSeed.Designer.cs @@ -0,0 +1,135 @@ +// +using System; +using GreadyPoang.DataLayer.Database; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace GreadyPoang.DataLayer.Migrations +{ + [DbContext(typeof(DataContext))] + [Migration("20250902122130_FixDateTimeSeed")] + partial class FixDateTimeSeed + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "9.0.8"); + + modelBuilder.Entity("GreadyPoang.EntityLayer.GamePoint", b => + { + b.Property("GamePointId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("GameDate") + .HasColumnType("TEXT"); + + b.Property("GameHeatId") + .HasColumnType("INTEGER"); + + b.Property("GameHeatRegNr") + .HasColumnType("INTEGER"); + + b.Property("GameRegPoints") + .HasColumnType("INTEGER"); + + b.Property("ParticipantId") + .HasColumnType("INTEGER"); + + b.HasKey("GamePointId"); + + b.ToTable("GamePoints"); + + b.HasData( + new + { + GamePointId = 1, + GameDate = new DateTime(2025, 10, 15, 20, 10, 15, 0, DateTimeKind.Unspecified), + GameHeatId = 0, + GameHeatRegNr = 1, + GameRegPoints = 1050, + ParticipantId = 1 + }, + new + { + GamePointId = 2, + GameDate = new DateTime(2025, 10, 15, 20, 15, 15, 0, DateTimeKind.Unspecified), + GameHeatId = 0, + GameHeatRegNr = 3, + GameRegPoints = 350, + ParticipantId = 1 + }, + new + { + GamePointId = 3, + GameDate = new DateTime(2025, 10, 15, 20, 12, 15, 0, DateTimeKind.Unspecified), + GameHeatId = 0, + GameHeatRegNr = 2, + GameRegPoints = 1000, + ParticipantId = 3 + }, + new + { + GamePointId = 4, + GameDate = new DateTime(2025, 10, 15, 20, 20, 15, 0, DateTimeKind.Unspecified), + GameHeatId = 0, + GameHeatRegNr = 4, + GameRegPoints = 400, + ParticipantId = 3 + }); + }); + + modelBuilder.Entity("GreadyPoang.EntityLayer.Participant", b => + { + b.Property("ParticipantId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Email") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("LastName") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("ParticipantId"); + + b.ToTable("Participants"); + + b.HasData( + new + { + ParticipantId = 1, + Email = "John.Doe@gmail.com", + FirstName = "John", + LastName = "Doe" + }, + new + { + ParticipantId = 2, + Email = "jb@gmail.com", + FirstName = "Jane", + LastName = "Black" + }, + new + { + ParticipantId = 3, + Email = "mw@gmail.com", + FirstName = "Mary", + LastName = "White" + }); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/GreadyPoang.DataLayer/Migrations/20250902122130_FixDateTimeSeed.cs b/GreadyPoang.DataLayer/Migrations/20250902122130_FixDateTimeSeed.cs new file mode 100644 index 0000000..5541faa --- /dev/null +++ b/GreadyPoang.DataLayer/Migrations/20250902122130_FixDateTimeSeed.cs @@ -0,0 +1,75 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace GreadyPoang.DataLayer.Migrations +{ + /// + public partial class FixDateTimeSeed : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.UpdateData( + table: "GamePoints", + keyColumn: "GamePointId", + keyValue: 1, + column: "GameDate", + value: new DateTime(2025, 10, 15, 20, 10, 15, 0, DateTimeKind.Unspecified)); + + migrationBuilder.UpdateData( + table: "GamePoints", + keyColumn: "GamePointId", + keyValue: 2, + column: "GameDate", + value: new DateTime(2025, 10, 15, 20, 15, 15, 0, DateTimeKind.Unspecified)); + + migrationBuilder.UpdateData( + table: "GamePoints", + keyColumn: "GamePointId", + keyValue: 3, + column: "GameDate", + value: new DateTime(2025, 10, 15, 20, 12, 15, 0, DateTimeKind.Unspecified)); + + migrationBuilder.UpdateData( + table: "GamePoints", + keyColumn: "GamePointId", + keyValue: 4, + column: "GameDate", + value: new DateTime(2025, 10, 15, 20, 20, 15, 0, DateTimeKind.Unspecified)); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.UpdateData( + table: "GamePoints", + keyColumn: "GamePointId", + keyValue: 1, + column: "GameDate", + value: new DateTime(2025, 9, 2, 14, 9, 34, 269, DateTimeKind.Local).AddTicks(5394)); + + migrationBuilder.UpdateData( + table: "GamePoints", + keyColumn: "GamePointId", + keyValue: 2, + column: "GameDate", + value: new DateTime(2025, 9, 2, 14, 9, 34, 269, DateTimeKind.Local).AddTicks(6081)); + + migrationBuilder.UpdateData( + table: "GamePoints", + keyColumn: "GamePointId", + keyValue: 3, + column: "GameDate", + value: new DateTime(2025, 9, 2, 14, 9, 34, 269, DateTimeKind.Local).AddTicks(6085)); + + migrationBuilder.UpdateData( + table: "GamePoints", + keyColumn: "GamePointId", + keyValue: 4, + column: "GameDate", + value: new DateTime(2025, 9, 2, 14, 9, 34, 269, DateTimeKind.Local).AddTicks(6088)); + } + } +} diff --git a/GreadyPoang.DataLayer/Migrations/DataContextModelSnapshot.cs b/GreadyPoang.DataLayer/Migrations/DataContextModelSnapshot.cs new file mode 100644 index 0000000..7474492 --- /dev/null +++ b/GreadyPoang.DataLayer/Migrations/DataContextModelSnapshot.cs @@ -0,0 +1,132 @@ +// +using System; +using GreadyPoang.DataLayer.Database; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace GreadyPoang.DataLayer.Migrations +{ + [DbContext(typeof(DataContext))] + partial class DataContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "9.0.8"); + + modelBuilder.Entity("GreadyPoang.EntityLayer.GamePoint", b => + { + b.Property("GamePointId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("GameDate") + .HasColumnType("TEXT"); + + b.Property("GameHeatId") + .HasColumnType("INTEGER"); + + b.Property("GameHeatRegNr") + .HasColumnType("INTEGER"); + + b.Property("GameRegPoints") + .HasColumnType("INTEGER"); + + b.Property("ParticipantId") + .HasColumnType("INTEGER"); + + b.HasKey("GamePointId"); + + b.ToTable("GamePoints"); + + b.HasData( + new + { + GamePointId = 1, + GameDate = new DateTime(2025, 10, 15, 20, 10, 15, 0, DateTimeKind.Unspecified), + GameHeatId = 0, + GameHeatRegNr = 1, + GameRegPoints = 1050, + ParticipantId = 1 + }, + new + { + GamePointId = 2, + GameDate = new DateTime(2025, 10, 15, 20, 15, 15, 0, DateTimeKind.Unspecified), + GameHeatId = 0, + GameHeatRegNr = 3, + GameRegPoints = 350, + ParticipantId = 1 + }, + new + { + GamePointId = 3, + GameDate = new DateTime(2025, 10, 15, 20, 12, 15, 0, DateTimeKind.Unspecified), + GameHeatId = 0, + GameHeatRegNr = 2, + GameRegPoints = 1000, + ParticipantId = 3 + }, + new + { + GamePointId = 4, + GameDate = new DateTime(2025, 10, 15, 20, 20, 15, 0, DateTimeKind.Unspecified), + GameHeatId = 0, + GameHeatRegNr = 4, + GameRegPoints = 400, + ParticipantId = 3 + }); + }); + + modelBuilder.Entity("GreadyPoang.EntityLayer.Participant", b => + { + b.Property("ParticipantId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Email") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("LastName") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("ParticipantId"); + + b.ToTable("Participants"); + + b.HasData( + new + { + ParticipantId = 1, + Email = "John.Doe@gmail.com", + FirstName = "John", + LastName = "Doe" + }, + new + { + ParticipantId = 2, + Email = "jb@gmail.com", + FirstName = "Jane", + LastName = "Black" + }, + new + { + ParticipantId = 3, + Email = "mw@gmail.com", + FirstName = "Mary", + LastName = "White" + }); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/GreadyPoang.EntityLayer/EntityClasses/GamePoint.cs b/GreadyPoang.EntityLayer/EntityClasses/GamePoint.cs new file mode 100644 index 0000000..877da13 --- /dev/null +++ b/GreadyPoang.EntityLayer/EntityClasses/GamePoint.cs @@ -0,0 +1,91 @@ +using Common.Library; +using SQLite; + +namespace GreadyPoang.EntityLayer; +[Table("GamePoint")] +public class GamePoint : EntityBase +{ + public GamePoint() + { + _gamePointId = 0; + _participantId = 0; + _gameHeatId = 0; + _gameDate = DateTime.Now; + _gameHeatRegNr = 0; + _gameRegPoints = 0; + } + + private int _gamePointId; + private int _participantId; + private int _gameHeatId; + private DateTime _gameDate; + private int _gameHeatRegNr; + private int _gameRegPoints; + + [PrimaryKey] + [AutoIncrement] + [Column("GamePointId")] + public int GamePointId + { + get { return _gamePointId; } + set + { + _gamePointId = value; + RaisePropertyChanged(nameof(GamePointId)); + } + } + + [Column("ParticipantId")] + public int ParticipantId + { + get { return _participantId; } + set + { + _participantId = value; + RaisePropertyChanged(nameof(ParticipantId)); + } + } + [Column("GameHeatId")] + public int GameHeatId + { + get { return _gameHeatId; } + set + { + _gameHeatId = value; + RaisePropertyChanged(nameof(GameHeatId)); + } + } + + [Column("GameDate")] + public DateTime GameDate + { + get { return _gameDate; } + set + { + _gameDate = value; + RaisePropertyChanged(nameof(GameDate)); + } + } + + [Column("GameHeatRegNr")] + public int GameHeatRegNr + { + get { return _gameHeatRegNr; } + set + { + _gameHeatRegNr = value; + RaisePropertyChanged(nameof(GameHeatRegNr)); + } + } + + [Column("GameRegPoints")] + public int GameRegPoints + { + get { return _gameRegPoints; } + set + { + _gameRegPoints = value; + RaisePropertyChanged(nameof(GameRegPoints)); + } + } +} diff --git a/GreadyPoang.Migrations/GreadyPoang.Migrations.csproj b/GreadyPoang.Migrations/GreadyPoang.Migrations.csproj new file mode 100644 index 0000000..d608574 --- /dev/null +++ b/GreadyPoang.Migrations/GreadyPoang.Migrations.csproj @@ -0,0 +1,24 @@ + + + + Exe + net9.0 + enable + enable + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + diff --git a/GreadyPoang.Migrations/Program.cs b/GreadyPoang.Migrations/Program.cs new file mode 100644 index 0000000..5f83079 --- /dev/null +++ b/GreadyPoang.Migrations/Program.cs @@ -0,0 +1,30 @@ +using GreadyPoang.DataLayer.Database; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Hosting; // Replace with your actual namespace + +class Program +{ + static void Main(string[] args) + { + using var host = CreateHostBuilder(args).Build(); + + // Resolve your DbContext + var context = host.Services.GetRequiredService(); + context.Database.EnsureCreated(); + // Optional: Apply migrations at runtime + context.Database.Migrate(); + + Console.WriteLine("Migration applied successfully."); + } + + static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureServices((_, services) => + { + var MauiDataPath = string.Empty; + MauiDataPath = File.ReadAllText(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "MauiDataPath_GreadyPoang.txt")); + var dbPath = Path.Combine(MauiDataPath, "PoangDB.db"); + services.AddDbContext(options => + options.UseSqlite($"Data Source={dbPath}")); + }); +} \ No newline at end of file diff --git a/GreadyPoang.ViewModelLayer/ViewModelClasses/ParticipantViewModel.cs b/GreadyPoang.ViewModelLayer/ViewModelClasses/ParticipantViewModel.cs index 77f5b00..62363d1 100644 --- a/GreadyPoang.ViewModelLayer/ViewModelClasses/ParticipantViewModel.cs +++ b/GreadyPoang.ViewModelLayer/ViewModelClasses/ParticipantViewModel.cs @@ -55,15 +55,22 @@ public class ParticipantViewModel : ViewModelBase #endregion #region Get Method - public async Task> GetAsync() + public ObservableCollection Get() { if (Repository != null) { - ParticipantList = await Repository.Get(); - return ParticipantList; + var participantsTask = Repository.Get(); + var participants = participantsTask is Task> task + ? task.GetAwaiter().GetResult() + : (IEnumerable)participantsTask; + foreach (var participant in participants) + { + if (!_ParticipantList.Any(p => p.ParticipantId == participant.ParticipantId)) + { + ParticipantList.Add(participant); + } + } } - - _ParticipantList = new ObservableCollection(); return ParticipantList; } @@ -74,7 +81,7 @@ public class ParticipantViewModel : ViewModelBase { try { - ParticipantObject = Repository.Get(id); + ParticipantObject = Repository?.Get(id).GetAwaiter().GetResult(); } catch (Exception ex) { @@ -89,11 +96,12 @@ public class ParticipantViewModel : ViewModelBase { return false; } - var tmp = Repository.Save(ParticipantObject); + var tmpTask = Repository.Save(ParticipantObject); + bool tmp = tmpTask.GetAwaiter().GetResult(); if (tmp) { ParticipantObject = new Participant(); - this.GetAsync(); + this.Get(); } return tmp; } diff --git a/GreadyPoang.sln b/GreadyPoang.sln index 396c6ed..7fc7203 100644 --- a/GreadyPoang.sln +++ b/GreadyPoang.sln @@ -13,6 +13,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GreadyPoang.ViewModelLayer" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GreadyPoang.DataLayer", "GreadyPoang.DataLayer\GreadyPoang.DataLayer.csproj", "{48BD841F-C383-4E0B-963E-AC2400FCC678}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GreadyPoang.Migrations", "GreadyPoang.Migrations\GreadyPoang.Migrations.csproj", "{56EB8207-E108-4498-82AC-BAC8966D3D2D}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -40,6 +42,10 @@ Global {48BD841F-C383-4E0B-963E-AC2400FCC678}.Debug|Any CPU.Build.0 = Debug|Any CPU {48BD841F-C383-4E0B-963E-AC2400FCC678}.Release|Any CPU.ActiveCfg = Release|Any CPU {48BD841F-C383-4E0B-963E-AC2400FCC678}.Release|Any CPU.Build.0 = Release|Any CPU + {56EB8207-E108-4498-82AC-BAC8966D3D2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {56EB8207-E108-4498-82AC-BAC8966D3D2D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {56EB8207-E108-4498-82AC-BAC8966D3D2D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {56EB8207-E108-4498-82AC-BAC8966D3D2D}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/GreadyPoang/GreadyPoang.csproj b/GreadyPoang/GreadyPoang.csproj index 85552f1..b261f6d 100644 --- a/GreadyPoang/GreadyPoang.csproj +++ b/GreadyPoang/GreadyPoang.csproj @@ -67,6 +67,7 @@ + diff --git a/GreadyPoang/MauiProgram.cs b/GreadyPoang/MauiProgram.cs index 0124623..6b13bdb 100644 --- a/GreadyPoang/MauiProgram.cs +++ b/GreadyPoang/MauiProgram.cs @@ -24,13 +24,18 @@ public static class MauiProgram builder.Services.AddDbContext(options => { - var dbPath = Path.Combine(FileSystem.Current.AppDataDirectory, "PoangDB"); + var MauiDataPath = FileSystem.Current.AppDataDirectory; + if (!File.Exists(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "MauiDataPath_GreadyPoang.txt"))) ; + { + File.WriteAllText(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "MauiDataPath_GreadyPoang.txt"), MauiDataPath); + } + //var dbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "PoangDB.db"); + var dbPath = Path.Combine(MauiDataPath, "PoangDB.db"); options.UseSqlite($"Data Source={dbPath}"); }); - builder.Services.AddSingleton(); builder.Services.AddScoped, ParticipantRepository>(); builder.Services.AddScoped(); builder.Services.AddScoped(); diff --git a/GreadyPoang/Views/ParticipantListView.xaml.cs b/GreadyPoang/Views/ParticipantListView.xaml.cs index f258454..e655933 100644 --- a/GreadyPoang/Views/ParticipantListView.xaml.cs +++ b/GreadyPoang/Views/ParticipantListView.xaml.cs @@ -17,7 +17,7 @@ public partial class ParticipantListView : ContentPage { base.OnAppearing(); BindingContext = ViewModel; - ViewModel.GetAsync(); + ViewModel.Get(); }