Files
Pf2eDataScrapper/Pf2eViewer/DatabaseViewer.cs
T

172 lines
4.6 KiB
C#

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<Entity> 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<Getter> _getters =
[
new Getter<Ancestry>(
EntityType.Ancestry,
context => context.Ancestries.Include(a => a.AncestryBoosts)
),
new Getter<Archetype>(
EntityType.Archetype,
context =>
context
.Archetypes.Include(a => a.DedicationFeat)
.ThenInclude(f => f.Entity)
.Include(a => a.Feats)
.ThenInclude(f => f.Entity)
),
new Getter<Background>(
EntityType.Background,
context =>
context
.Backgrounds.Include(b => b.BackgroundBoosts)
.Include(b => b.BackgroundSkills)
.ThenInclude(t => t.Training)
.Include(b => b.BackgroundItems)
),
new Getter<Class>(
EntityType.Class,
context =>
context
.Classes.Include(c => c.ClassKeyAbilities)
.Include(c => c.ClassTrainings)
.ThenInclude(t => t.Training)
.Include(c => c.ClassProgressions)
),
new Getter<Feat>(
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<T>(EntityType type, Func<Pf2eDbContext, IQueryable<T>> method)
: Getter(type)
where T : IEntity
{
public override IEntity? Get(int id, Pf2eDbContext context)
{
return method.Invoke(context).FirstOrDefault(c => c.Id == id);
}
}
}