Update search provider sort logic, and added testing for circle search provider.

This commit is contained in:
2025-08-30 16:21:35 -04:00
parent f221deea36
commit 516060963e
11 changed files with 435 additions and 143 deletions

View File

@@ -16,7 +16,7 @@ public abstract class SearchProvider<TItem, TCriteria, TSortField, TBaseQuery> :
int total = await filteredQuery.CountAsync(cancellationToken);
IOrderedQueryable<TBaseQuery> orderedQuery = ApplySorting(filteredQuery, options.SortOptions);
IOrderedQueryable<TItem> selectQuery = GetSelectQuery(orderedQuery);
IQueryable<TItem> selectQuery = GetSelectQuery(orderedQuery);
TItem[] items = await selectQuery
.Skip((options.PageNumber - 1) * options.PageSize)
@@ -50,10 +50,40 @@ public abstract class SearchProvider<TItem, TCriteria, TSortField, TBaseQuery> :
ordered = (i == 0) ? applyFirst(selector) : applyNext(selector);
}
return ordered ?? GetDefaultSortExpression(query);
//return ordered ?? GetDefaultSortExpression(query);
// Always add the default as the final tiebreaker
var chain = GetDefaultSortChain();
if (ordered is null)
{
using var e = chain.GetEnumerator();
if (!e.MoveNext()) throw new InvalidOperationException("No default sort provided.");
var (Selector, Dir) = e.Current;
var res = Dir == SortDirection.Descending
? query.OrderByDescending(Selector)
: query.OrderBy(Selector);
while (e.MoveNext())
res = e.Current.Dir == SortDirection.Descending
? res.ThenByDescending(e.Current.Selector)
: res.ThenBy(e.Current.Selector);
return res;
}
else
{
var res = ordered;
foreach (var (sel, dir) in chain)
res = dir == SortDirection.Descending ? res.ThenByDescending(sel) : res.ThenBy(sel);
return res;
}
}
protected abstract Expression<Func<TBaseQuery, object>> GetSortExpression(TSortField field);
protected abstract IOrderedQueryable<TBaseQuery> GetDefaultSortExpression(IQueryable<TBaseQuery> query);
protected abstract IOrderedQueryable<TItem> GetSelectQuery(IOrderedQueryable<TBaseQuery> query);
//protected abstract (Expression<Func<TBaseQuery, object>> Selector, SortDirection Direction) GetDefaultSortExpression();
protected abstract IEnumerable<(Expression<Func<TBaseQuery, object>> Selector, SortDirection Dir)> GetDefaultSortChain();
protected abstract IQueryable<TItem> GetSelectQuery(IOrderedQueryable<TBaseQuery> query);
}