Updated search logic. More UI updates.
This commit is contained in:
@@ -8,6 +8,8 @@ public abstract class SearchProvider<TItem, TCriteria, TSortField, TBaseQuery> :
|
||||
where TCriteria : new()
|
||||
where TSortField : struct, Enum
|
||||
{
|
||||
protected abstract bool UseSelectIdQuery { get; }
|
||||
|
||||
public async Task<SearchResult<TItem>> SearchAsync(SearchOptions<TCriteria, TSortField> options, CancellationToken cancellationToken = default)
|
||||
{
|
||||
IQueryable<TBaseQuery> baseQuery = GetBaseQuery();
|
||||
@@ -16,12 +18,7 @@ public abstract class SearchProvider<TItem, TCriteria, TSortField, TBaseQuery> :
|
||||
int total = await filteredQuery.CountAsync(cancellationToken);
|
||||
|
||||
IOrderedQueryable<TBaseQuery> orderedQuery = ApplySorting(filteredQuery, options.SortOptions);
|
||||
IQueryable<TItem> selectQuery = GetSelectQuery(orderedQuery);
|
||||
|
||||
TItem[] items = await selectQuery
|
||||
.Skip((options.PageNumber - 1) * options.PageSize)
|
||||
.Take(options.PageSize)
|
||||
.ToArrayAsync(cancellationToken);
|
||||
TItem[] items = await GetItemsAsync(options, orderedQuery, cancellationToken);
|
||||
|
||||
await PostLoadAsync(items, cancellationToken);
|
||||
|
||||
@@ -44,10 +41,10 @@ public abstract class SearchProvider<TItem, TCriteria, TSortField, TBaseQuery> :
|
||||
var (field, direction) = (sortOptions[i].Field, sortOptions[i].Direction);
|
||||
bool isDescending = direction == SortDirection.Descending;
|
||||
|
||||
IOrderedQueryable<TBaseQuery> applyFirst(Expression<Func<TBaseQuery, object>> selector) => isDescending ? query.OrderByDescending(selector) : query.OrderBy(selector);
|
||||
IOrderedQueryable<TBaseQuery> applyNext(Expression<Func<TBaseQuery, object>> selector) => isDescending ? ordered!.ThenByDescending(selector) : ordered!.ThenBy(selector);
|
||||
IOrderedQueryable<TBaseQuery> applyFirst(Expression<Func<TBaseQuery, object?>> selector) => isDescending ? query.OrderByDescending(selector) : query.OrderBy(selector);
|
||||
IOrderedQueryable<TBaseQuery> applyNext(Expression<Func<TBaseQuery, object?>> selector) => isDescending ? ordered!.ThenByDescending(selector) : ordered!.ThenBy(selector);
|
||||
|
||||
Expression<Func<TBaseQuery, object>> selector = GetSortExpression(field);
|
||||
Expression<Func<TBaseQuery, object?>> selector = GetSortExpression(field);
|
||||
|
||||
ordered = (i == 0) ? applyFirst(selector) : applyNext(selector);
|
||||
}
|
||||
@@ -83,8 +80,34 @@ public abstract class SearchProvider<TItem, TCriteria, TSortField, TBaseQuery> :
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract Expression<Func<TBaseQuery, object>> GetSortExpression(TSortField field);
|
||||
private async Task<TItem[]> GetItemsAsync(SearchOptions<TCriteria, TSortField> options, IOrderedQueryable<TBaseQuery> orderedQuery, CancellationToken cancellationToken)
|
||||
{
|
||||
if (UseSelectIdQuery)
|
||||
{
|
||||
int[] ids = await GetSelectIdQuery(orderedQuery)
|
||||
.Skip((options.PageNumber - 1) * options.PageSize)
|
||||
.Take(options.PageSize)
|
||||
.ToArrayAsync(cancellationToken);
|
||||
|
||||
Dictionary<int, TItem> items = await GetItems(ids);
|
||||
|
||||
return [.. ids.Select(uniqueId => items[uniqueId])];
|
||||
}
|
||||
else
|
||||
{
|
||||
IQueryable<TItem> selectQuery = GetSelectQuery(orderedQuery);
|
||||
|
||||
return await selectQuery
|
||||
.Skip((options.PageNumber - 1) * options.PageSize)
|
||||
.Take(options.PageSize)
|
||||
.ToArrayAsync(cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract Expression<Func<TBaseQuery, object?>> GetSortExpression(TSortField field);
|
||||
protected abstract IEnumerable<(Expression<Func<TBaseQuery, object>> Selector, SortDirection Dir)> GetDefaultSortChain();
|
||||
protected abstract IQueryable<int> GetSelectIdQuery(IOrderedQueryable<TBaseQuery> query);
|
||||
protected abstract IQueryable<TItem> GetSelectQuery(IOrderedQueryable<TBaseQuery> query);
|
||||
protected abstract Task<Dictionary<int, TItem>> GetItems(int[] ids);
|
||||
protected virtual Task PostLoadAsync(IList<TItem> items, CancellationToken cancellationToken) => Task.CompletedTask;
|
||||
}
|
||||
Reference in New Issue
Block a user