using LanguageExt.Common; using Microsoft.EntityFrameworkCore; using W542.GandalfReborn.Data.Entities.Base; using W542.GandalfReborn.Data.Entities.Tenant; namespace W542.GandalfReborn.Data.Database.Repositories; public abstract class GrRepository(ApplicationContext context) : IGrRepository where TEntity : class, IEntity { public async Task> SaveChanges() { try { await context.SaveChangesAsync(); return true; } catch (Exception e) { return new Result(e); } } public async Task> GetSingle(Func, IQueryable>? query, bool tracked = true) { IQueryable set = context.Set(); if (query is not null) { set = query.Invoke(set); } if (!tracked) { set = set.AsNoTracking(); } var result = await set.SingleOrDefaultAsync(); return result ?? new Result(new Exception("Not found.")); } public async Task>> GetMany(Func, IQueryable>? query, bool tracked = true) { IQueryable set = context.Set(); if (query is not null) { set = query.Invoke(set); } if (!tracked) { set = set.AsNoTracking(); } var result = await set.ToListAsync(); return result; } public async Task> Upsert(TEntity entity) { var result = await Upsert([entity]); return result.Match( success => { if (success.Count != 1) { return new Result(new Exception("Something very sus happened during upsert. Input count != output count?")); } return success.Single(); }, fail => new Result(fail) ); } public async Task>> Upsert(ICollection entities) { var newEntities = entities.Where(x => x.Id is null).ToList(); var updatedEntities = entities.Where(x => x.Id is not null).ToList(); try { context.AddRange(newEntities); context.UpdateRange(updatedEntities); await context.SaveChangesAsync(); } catch (Exception e) { return new Result>(e); } return new Result>(entities); } public IQueryable Query(Func, IQueryable> query) { return Query(query); } private IQueryable Query(Func, IQueryable> query) where TIn : class, IEntity { IQueryable set = context.Set(); return query.Invoke(set); } public IQueryable Query(Func, IQueryable> query) { return Query(query); } }