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();
}