using Microsoft.EntityFrameworkCore; using Prefab.Data.Entities; using Prefab.Domain.Common; namespace Prefab.Data.Queries; /// /// Provides extension methods for the entity. /// public static class GenericAttributeQueries { /// /// Query for records where the field matches the given entity. /// public static IQueryable ForEntity(this IQueryable query, IEntity entity) { ArgumentNullException.ThrowIfNull(entity); return query.Where(x => x.EntityId == entity.Id && x.KeyGroup == entity.GetType().FullName); } /// /// Query for records in a module-specific view where the EntityId matches the given entity. /// public static IQueryable ForEntity(this IQueryable query, IEntity entity, string keyGroup) where TView : class { return GenericAttributeViewQueries.ForEntity(query, entity, keyGroup); } /// /// Query for records where the field contains characters from the given string value. /// public static IQueryable WhereTheValueContains(this IQueryable query, string value) { return query.Where(x => x.Value.Contains(value)); } /// /// Filter by key (exact match). /// private static IQueryable WhereKey( this IQueryable q, string key) => q.Where(x => x.Key == key); /// /// Filter by key-group (exact match). /// public static IQueryable WhereGroup( this IQueryable q, string keyGroup) => q.Where(x => x.KeyGroup == keyGroup); /// /// Filter by type (exact match). /// public static IQueryable WhereType( this IQueryable q, string type) => q.Where(x => x.Type == type); /// /// Filter by any of the given keys. /// public static IQueryable WhereKeys( this IQueryable q, params string[] keys) => q.Where(x => keys.Contains(x.Key)); /// /// Case-insensitive substring search on Value using EF.Functions.Like. /// public static IQueryable WhereValueLike( this IQueryable q, string pattern) => q.Where(x => EF.Functions.Like(x.Value, pattern)); /// /// Project into a key→value dictionary. /// public static async Task> ToDictionaryAsync( this IQueryable q, CancellationToken ct = default) { return await q .Select(x => new { x.Key, x.Value }) .ToDictionaryAsync(x => x.Key, x => x.Value, ct) .ConfigureAwait(false); } /// /// Shortcut to fetch a single attribute value (or null). /// public static async Task GetValueAsync( this IQueryable q, string key, CancellationToken ct = default) { return await q .WhereKey(key) .Select(x => x.Value) .FirstOrDefaultAsync(ct) .ConfigureAwait(false); } /// /// Apply AsNoTracking for read-only queries. /// public static IQueryable AsReadOnly( this IQueryable q) => q.AsNoTracking(); }