using LinqToDB.SqlQuery; using LinqToDB.Tools; using Microsoft.EntityFrameworkCore; using Pf2eModel; using Pf2eModel.Model; using Pf2eModel.Model.Base; using Pf2eModel.Model.Enum; using Pf2eModel.Model.Structure; namespace Pf2eViewer; public class DatabaseViewer { public readonly Pf2eDbContext Context = new(); private int _perPage = 30; private int _page = 1; private EntityType _entityType; public int PerPage { get => _perPage; set { _perPage = value; UpdateView(); } } public int Page { get => _page; set { _page = value; UpdateView(); } } public EntityType EntityType { get => _entityType; set { _entityType = value; UpdateView(); } } public int Count { get; private set; } public int MaxPage => Convert.ToInt32(Math.Ceiling(1.0 * Count / PerPage)); public ICollection Entities { get; private set; } = []; public delegate void ViewUpdateHandler(); public event ViewUpdateHandler? ViewUpdateStart; public event ViewUpdateHandler? ViewUpdate; public Entity? LastEntity; public IEntity? LastSubEntity; public delegate void ViewSelectHandler(Entity? entity, IEntity? subEntity); public event ViewSelectHandler? ViewSelect; public void UpdateView() { ViewUpdateStart?.Invoke(); Count = Context.Entities.Count(e => e.Type == EntityType); if (_page < 1 || _page > MaxPage) { _page = Math.Min(MaxPage, Math.Max(1, _page)); } Entities = Context .Entities.Where(e => e.Type == EntityType) .OrderBy(e => e.Id) .Skip((Page - 1) * PerPage) .Take(PerPage) .ToList(); ViewUpdate?.Invoke(); } public void Select(Entity entity) { Getter? getter = _getters.FirstOrDefault(g => g.Type == entity.Type); Entity? fullEntity = Context .Entities.Where(e => e.Id == entity.Id && e.Type == entity.Type) .Include(e => e.Sources) .ThenInclude(s => s.Source) .Include(e => e.Keywords) .Include(e => e.Externals) .ThenInclude(x => x.Target) .Include(e => e.Traits) .ThenInclude(t => t.Entity) .FirstOrDefault(); IEntity? subEntity = (getter != null) ? getter.Get(entity.Id, Context) : (IEntity?)Context.Find(EntityOfTypeAttribute.Resolve(entity), entity.Id); ViewSelect?.Invoke(fullEntity, subEntity); LastEntity = fullEntity; LastSubEntity = subEntity; } private readonly ICollection _getters = [ new Getter( EntityType.Ancestry, context => context.Ancestries.Include(a => a.AncestryBoosts) ), new Getter( EntityType.Archetype, context => context .Archetypes.Include(a => a.DedicationFeat) .ThenInclude(f => f.Entity) .Include(a => a.Feats) .ThenInclude(f => f.Entity) ), new Getter( EntityType.Background, context => context .Backgrounds.Include(b => b.BackgroundBoosts) .Include(b => b.BackgroundSkills) .ThenInclude(t => t.Training) .Include(b => b.BackgroundItems) ), new Getter( EntityType.Class, context => context .Classes.Include(c => c.ClassKeyAbilities) .Include(c => c.ClassTrainings) .ThenInclude(t => t.Training) .Include(c => c.ClassProgressions) ), new Getter( EntityType.Feat, context => context.Feats.Include(f => f.Archetypes).ThenInclude(a => a.Entity).AsQueryable() ), ]; private abstract class Getter(EntityType type) { public readonly EntityType Type = type; public abstract IEntity? Get(int id, Pf2eDbContext context); } private class Getter(EntityType type, Func> method) : Getter(type) where T : IEntity { public override IEntity? Get(int id, Pf2eDbContext context) { return method.Invoke(context).FirstOrDefault(c => c.Id == id); } } }