public static IQueryable <T> ApplySortExpression <T>(this ISortOptions options, IQueryable <T> queryable) { if (string.IsNullOrEmpty(options.SortExpression)) { return(queryable); } var type = typeof(T); var property = type.GetTypeInfo().GetProperty(options.SortExpression); if (property == null) { throw new Exception($"Could not sort by property '{options.SortExpression}', since it does not exists."); } var parameter = Expression.Parameter(type, "p"); var propertyAccess = Expression.MakeMemberAccess(parameter, property); var orderBy = Expression.Lambda(propertyAccess, parameter); var result = Expression.Call(typeof(Queryable), GetSortingMethodName(options), new[] { type, property.PropertyType }, queryable.Expression, Expression.Quote(orderBy)); return(queryable.Provider.CreateQuery <T>(result)); }
private static IOrderedQueryable <TModel> ApplyOptions <TModel>( this IQueryable <TModel> query, ISortOptions options) where TModel : IQueryModel { var propertySelectorExpression = ReflectionHelper .GetPropertySelectorExpressionFor <TModel, IComparable>( options.PropertyName); return(options.SortDirection == SortDirection.Ascending ? query.OrderBy(propertySelectorExpression) : query.OrderByDescending(propertySelectorExpression)); }
public static IQueryable <T> ApplySort <T>(this IQueryable <T> query, ISortOptions options) { if (options?.OrderBy?.Length > 0) { var _orderBy = options.OrderBy; var orderByLength = _orderBy.Length; // get given type's properties var properties = typeof(T).GetProperties(); var propertiesLength = properties.Length; bool useThenBy = false; // iterate over all terms for (int i = 0; i < orderByLength; i++) { // if invalid term then skip it if (string.IsNullOrEmpty(_orderBy[i])) { continue; } var tokens = _orderBy[i].Split(' '); if (tokens.Length != 0) { for (int j = 0; j < propertiesLength; j++) { // if property has sortable attribute and sort term equals to property name bool hasSortableAttribute = properties[j].GetCustomAttributes <SortableAttribute>().Count() > 0 && properties[j].Name.Equals(tokens[0], StringComparison.OrdinalIgnoreCase); if (hasSortableAttribute) { bool decending = tokens.Length > 1 && tokens[1].Equals(decendingString, StringComparison.OrdinalIgnoreCase); // build expression query var property = ExpressionUtilities.GetPropertyInfo <T>(properties[j].Name); var parameter = ExpressionUtilities.Parameter <T>(); var key = ExpressionUtilities.GetPropertyExpression(parameter, property); var lambda = ExpressionUtilities.GetLambda(typeof(T), property.PropertyType, parameter, key); // query.OrderBy/ThenBy[Decending](x => x.Property) query = ExpressionUtilities.CallOrderByOrThenBy(query, useThenBy, decending, property.PropertyType, lambda); useThenBy = true; break; } } } } } return(query); }
/// <summary> /// Performs a search using the specified <paramref name="sortOptions"/>. /// </summary> /// <param name="operation">The boolean operation the search should be based on.</param> /// <param name="sortOptions">The sort options specyfing how the results should be sorted.</param> /// <param name="results">The results of the search.</param> /// <param name="total">The total amount of results returned by the search.</param> protected virtual void Execute(IBooleanOperation operation, ISortOptions sortOptions, out IEnumerable <ISearchResult> results, out long total) { // Cast the boolean operation to IQueryExecutor IQueryExecutor executor = operation; // If "SortField" doesn't specified, we don't apply any sorting if (!string.IsNullOrWhiteSpace(sortOptions.SortField)) { switch (sortOptions.SortOrder) { case SortOrder.Ascending: executor = operation.OrderBy(new SortableField(sortOptions.SortField, sortOptions.SortType)); break; case SortOrder.Descending: executor = operation.OrderByDescending(new SortableField(sortOptions.SortField, sortOptions.SortType)); break; default: throw new Exception($"Unsupported sort order: {sortOptions.SortOrder}"); } } if (sortOptions is IOffsetOptions offset) { ISearchResults allResults = executor.Execute(); // Update the total amount of results total = allResults.TotalItemCount; // Apply limit and offset results = allResults .Skip(offset.Offset) .Take(offset.Limit); } else { // Since no offset or limit is specified, we request all results ISearchResults allResults = executor.Execute(int.MaxValue); // Update the total amount of results total = allResults.TotalItemCount; // Update "results" with the value of "allResults" as we're not filtering the results results = allResults; } }
private static string GetSortingMethodName(ISortOptions options) { return(options.SortDescending ? "OrderByDescending" : "OrderBy"); }