From b04fc7e06e7ce59b1e3b4d55870b42a11d91a881 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tommy=20=C3=96man?= Date: Mon, 1 Sep 2025 11:14:38 +0200 Subject: [PATCH] =?UTF-8?q?F=C3=B6rberett=20f=C3=B6r=20=C3=B6verg=C3=A5ng?= =?UTF-8?q?=20till=20entity=20framework?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Common.Library/BaseClasses/ViewModelBase.cs | 11 ++- Common.Library/Common.Library.csproj | 1 + Common.Library/Interfaces/IRepository.cs | 2 +- .../DataClasses/LocalDbService.cs | 46 +++++++++ .../DataClasses/ParticipantRepository.cs | 93 ++++++++++--------- GreadyPoang.DataLayer/Database/DataContext.cs | 25 +++++ .../GreadyPoang.DataLayer.csproj | 2 + .../EntityClasses/Participant.cs | 10 +- .../GreadyPoang.EntityLayer.csproj | 4 + .../ViewModelClasses/ParticipantViewModel.cs | 15 ++- GreadyPoang/GreadyPoang.csproj | 3 +- GreadyPoang/MauiProgram.cs | 50 ++++++---- GreadyPoang/Views/ParticipantListView.xaml.cs | 2 +- 13 files changed, 191 insertions(+), 73 deletions(-) create mode 100644 GreadyPoang.DataLayer/DataClasses/LocalDbService.cs create mode 100644 GreadyPoang.DataLayer/Database/DataContext.cs diff --git a/Common.Library/BaseClasses/ViewModelBase.cs b/Common.Library/BaseClasses/ViewModelBase.cs index 4095130..e33b2e7 100644 --- a/Common.Library/BaseClasses/ViewModelBase.cs +++ b/Common.Library/BaseClasses/ViewModelBase.cs @@ -1,5 +1,14 @@ -namespace Common.Library; +//using GreadyPoang.DataLayer; + +namespace Common.Library; public class ViewModelBase : CommonBase { + //private readonly LocalDbService _dbService; + + //public ViewModelBase(LocalDbService dbService) + //{ + // _dbService = dbService; + //} + } diff --git a/Common.Library/Common.Library.csproj b/Common.Library/Common.Library.csproj index 125f4c9..069991c 100644 --- a/Common.Library/Common.Library.csproj +++ b/Common.Library/Common.Library.csproj @@ -6,4 +6,5 @@ enable + diff --git a/Common.Library/Interfaces/IRepository.cs b/Common.Library/Interfaces/IRepository.cs index e53b0ea..a2e77d0 100644 --- a/Common.Library/Interfaces/IRepository.cs +++ b/Common.Library/Interfaces/IRepository.cs @@ -4,7 +4,7 @@ namespace Common.Library; public interface IRepository { - ObservableCollection Get(); + Task> Get(); TEntity Get(int id); bool Save(TEntity entity); } diff --git a/GreadyPoang.DataLayer/DataClasses/LocalDbService.cs b/GreadyPoang.DataLayer/DataClasses/LocalDbService.cs new file mode 100644 index 0000000..ba17d5a --- /dev/null +++ b/GreadyPoang.DataLayer/DataClasses/LocalDbService.cs @@ -0,0 +1,46 @@ +using GreadyPoang.EntityLayer; +using SQLite; + +namespace GreadyPoang.DataLayer; + +public class LocalDbService +{ + private const string DB_NAME = "PoangDB"; + private readonly SQLiteAsyncConnection _connection; + + public LocalDbService() + { + //string dbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), DB_NAME); + string dbPath = Path.Combine(FileSystem.Current.AppDataDirectory, DB_NAME); + _connection = new SQLiteAsyncConnection(dbPath); + _connection.CreateTableAsync().Wait(); + } + + public async Task> GetParticipantsAsync() + { + return await _connection.Table().ToListAsync(); + } + + public async Task GetParticipantAsync(int id) + { + return await _connection.Table().Where(p => p.ParticipantId == id).FirstOrDefaultAsync(); + } + + public async Task SaveParticipantAsync(Participant participant) + { + if (participant.ParticipantId != 0) + { + return await _connection.UpdateAsync(participant); + } + else + { + return await _connection.InsertAsync(participant); + } + } + + public async Task DeleteParticipantAsync(Participant participant) + { + return await _connection.DeleteAsync(participant); + } + +} diff --git a/GreadyPoang.DataLayer/DataClasses/ParticipantRepository.cs b/GreadyPoang.DataLayer/DataClasses/ParticipantRepository.cs index 84fed75..0c67db8 100644 --- a/GreadyPoang.DataLayer/DataClasses/ParticipantRepository.cs +++ b/GreadyPoang.DataLayer/DataClasses/ParticipantRepository.cs @@ -6,78 +6,83 @@ namespace GreadyPoang.DataLayer; public class ParticipantRepository : IRepository { - + private readonly LocalDbService _dbService; private ObservableCollection lager; - public ParticipantRepository() + public ParticipantRepository(LocalDbService dbService) { if (lager == null || lager.Count == 0) { lager = new ObservableCollection(); - - lager.Add(new Participant - { - ParticipantId = 1, - FirstName = @"Kalle", - LastName = @"Persson", - Email = @"kalle@person.com", - }); - lager.Add(new Participant - { - ParticipantId = 2, - FirstName = @"Olle", - LastName = @"Goop", - Email = @"olle@goop.com", - }); - lager.Add(new Participant - { - ParticipantId = 3, - FirstName = @"Nisse", - LastName = @"Pärlemo", - Email = @"nisse@parlemo.com" - }); } + _dbService = dbService; } #region Get Method - public ObservableCollection 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) + { + foreach (var participant in result) + { + if (!lager.Any(p => p.ParticipantId == participant.ParticipantId)) + { + lager.Add(participant); + } + } + } + return lager; } public Participant? Get(int id) { - return Get().Where(row => row.ParticipantId == id).FirstOrDefault(); + Participant? participant = null; // Initialize the variable to avoid CS0165 + _dbService.GetParticipantAsync(id).ContinueWith(task => + { + 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(); + + return participant; } #endregion public bool Save(Participant entity) { - if (entity.ParticipantId == 0) + var output = false; + try { - // New entity - var maxId = lager.Max(p => p.ParticipantId); - entity.ParticipantId = maxId + 1; + _dbService.SaveParticipantAsync(entity).Wait(); lager.Add(entity); + output = true; } - else + catch (Exception ex) { - // Existing entity - var existing = Get(entity.ParticipantId); - if (existing != null) - { - existing.FirstName = entity.FirstName; - existing.LastName = entity.LastName; - existing.Email = entity.Email; - } - else - { - return false; // Entity not found - } + System.Diagnostics.Debug.WriteLine($"Error saving participants: {ex.Message}"); } - return true; + return output; + } } diff --git a/GreadyPoang.DataLayer/Database/DataContext.cs b/GreadyPoang.DataLayer/Database/DataContext.cs new file mode 100644 index 0000000..3222408 --- /dev/null +++ b/GreadyPoang.DataLayer/Database/DataContext.cs @@ -0,0 +1,25 @@ +using GreadyPoang.EntityLayer; +using Microsoft.EntityFrameworkCore; + +namespace GreadyPoang.DataLayer.Database +{ + public class DataContext : DbContext + { + public DataContext(DbContextOptions options) : base(options) + { + + } + //public DbSet Users => Set(); + public DbSet Participants { 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" } + ); + } + } +} diff --git a/GreadyPoang.DataLayer/GreadyPoang.DataLayer.csproj b/GreadyPoang.DataLayer/GreadyPoang.DataLayer.csproj index b08b128..f1393fc 100644 --- a/GreadyPoang.DataLayer/GreadyPoang.DataLayer.csproj +++ b/GreadyPoang.DataLayer/GreadyPoang.DataLayer.csproj @@ -7,6 +7,8 @@ + + diff --git a/GreadyPoang.EntityLayer/EntityClasses/Participant.cs b/GreadyPoang.EntityLayer/EntityClasses/Participant.cs index cf0cce6..b18b9bd 100644 --- a/GreadyPoang.EntityLayer/EntityClasses/Participant.cs +++ b/GreadyPoang.EntityLayer/EntityClasses/Participant.cs @@ -1,7 +1,8 @@ using Common.Library; +using SQLite; namespace GreadyPoang.EntityLayer; - +[Table("Participants")] public class Participant : EntityBase { public Participant() @@ -16,6 +17,9 @@ public class Participant : EntityBase private string _lastName; private string _email; + [PrimaryKey] + [AutoIncrement] + [Column("ParticipantId")] public int ParticipantId { get { return _participantId; } @@ -26,6 +30,7 @@ public class Participant : EntityBase } } + [Column("FirstName")] public string FirstName { get { return _firstName; } @@ -36,6 +41,7 @@ public class Participant : EntityBase } } + [Column("LastName")] public string LastName { get { return _lastName; } @@ -45,6 +51,8 @@ public class Participant : EntityBase RaisePropertyChanged(nameof(LastName)); } } + + [Column("Email")] public string Email { get { return _email; } diff --git a/GreadyPoang.EntityLayer/GreadyPoang.EntityLayer.csproj b/GreadyPoang.EntityLayer/GreadyPoang.EntityLayer.csproj index b6922ab..167f71d 100644 --- a/GreadyPoang.EntityLayer/GreadyPoang.EntityLayer.csproj +++ b/GreadyPoang.EntityLayer/GreadyPoang.EntityLayer.csproj @@ -10,4 +10,8 @@ + + + + diff --git a/GreadyPoang.ViewModelLayer/ViewModelClasses/ParticipantViewModel.cs b/GreadyPoang.ViewModelLayer/ViewModelClasses/ParticipantViewModel.cs index 65fa57b..77f5b00 100644 --- a/GreadyPoang.ViewModelLayer/ViewModelClasses/ParticipantViewModel.cs +++ b/GreadyPoang.ViewModelLayer/ViewModelClasses/ParticipantViewModel.cs @@ -17,6 +17,11 @@ public class ParticipantViewModel : ViewModelBase { Repository = repo; } + + //public ParticipantViewModel(IRepository repo) : base() + //{ + // Repository = repo; + //} #endregion #region Private Variables @@ -50,14 +55,16 @@ public class ParticipantViewModel : ViewModelBase #endregion #region Get Method - public ObservableCollection Get() + public async Task> GetAsync() { if (Repository != null) { - ParticipantList = new ObservableCollection(Repository.Get()); + ParticipantList = await Repository.Get(); + return ParticipantList; } - return new(); + _ParticipantList = new ObservableCollection(); + return ParticipantList; } #endregion @@ -86,7 +93,7 @@ public class ParticipantViewModel : ViewModelBase if (tmp) { ParticipantObject = new Participant(); - this.Get(); + this.GetAsync(); } return tmp; } diff --git a/GreadyPoang/GreadyPoang.csproj b/GreadyPoang/GreadyPoang.csproj index 39dcc9b..85552f1 100644 --- a/GreadyPoang/GreadyPoang.csproj +++ b/GreadyPoang/GreadyPoang.csproj @@ -60,8 +60,9 @@ - + + diff --git a/GreadyPoang/MauiProgram.cs b/GreadyPoang/MauiProgram.cs index 38b96b6..0124623 100644 --- a/GreadyPoang/MauiProgram.cs +++ b/GreadyPoang/MauiProgram.cs @@ -1,34 +1,44 @@ using Common.Library; using GreadyPoang.CommandClasses; using GreadyPoang.DataLayer; +using GreadyPoang.DataLayer.Database; using GreadyPoang.EntityLayer; using GreadyPoang.Views; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; -namespace GreadyPoang -{ - public static class MauiProgram - { - public static MauiApp CreateMauiApp() - { - var builder = MauiApp.CreateBuilder(); - builder - .UseMauiApp() - .ConfigureFonts(fonts => - { - fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular"); - fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold"); - }); +namespace GreadyPoang; - builder.Services.AddScoped, ParticipantRepository>(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); +public static class MauiProgram +{ + public static MauiApp CreateMauiApp() + { + var builder = MauiApp.CreateBuilder(); + builder + .UseMauiApp() + .ConfigureFonts(fonts => + { + fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular"); + fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold"); + }); + + builder.Services.AddDbContext(options => + { + var dbPath = Path.Combine(FileSystem.Current.AppDataDirectory, "PoangDB"); + options.UseSqlite($"Data Source={dbPath}"); + }); + + + + builder.Services.AddSingleton(); + builder.Services.AddScoped, ParticipantRepository>(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); #if DEBUG - builder.Logging.AddDebug(); + builder.Logging.AddDebug(); #endif - return builder.Build(); - } + return builder.Build(); } } diff --git a/GreadyPoang/Views/ParticipantListView.xaml.cs b/GreadyPoang/Views/ParticipantListView.xaml.cs index e655933..f258454 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.Get(); + ViewModel.GetAsync(); }