-
-
Notifications
You must be signed in to change notification settings - Fork 368
Closed
Labels
questionQuestion that needs to be answeredQuestion that needs to be answered
Milestone
Description
Is there an existing issue for this?
- I have searched the existing issues
Is your feature request related to a problem? Please describe the problem.
The class BootstrapBlazor.Components.QueryPageOptionsExtensions contains methods for converting what's in QueryPageOptions to LINQ, but not the sort options.
I think you need something like this:
public static class MoreQueryPageOptionsExtensions
{
/// <summary>
///
/// </summary>
/// <typeparam name="T">
/// <para>Must be an EF entity in order to transpile the whole query chain to SQL.</para>
/// <para>If not then use an anonymous type with the mapped entity as a property and use the complexProperty parameter on the other overload.</para>
///
/// </typeparam>
/// <param name="source"></param>
/// <param name="options"></param>
/// <returns></returns>
public static IQueryable<T> Apply<T>(this IQueryable<T> source, QueryPageOptions? options)
{
return Apply<T, T>(source, options, z => z);
}
public static IQueryable<T> Apply<T, U>(this IQueryable<T> source, QueryPageOptions? options, Expression<Func<T, U>> complexProperty)
{
if(options == null) { return source; }
return source
.Where(z => BootstrapBlazor.Components.QueryPageOptionsExtensions.ToFilterFunc<T>(options)(z))
.Order(options, complexProperty)
.Skip(options.PageIndex * options.PageItems).Take(options.PageItems);
}
private static IQueryable<T> Order<T, U>(this IQueryable<T> source, QueryPageOptions options, Expression<Func<T, U>> complexProperty)
{
if (string.IsNullOrEmpty(options.SortName)) { return source; }
MemberExpression cPme = (MemberExpression)complexProperty.Body;
// https://stackoverflow.com/questions/16208214/construct-lambdaexpression-for-nested-property-from-string
ParameterExpression z = Expression.Parameter(typeof(T), "z");
MemberExpression zm = Expression.PropertyOrField(z, cPme.Member.Name);
zm = Expression.PropertyOrField(zm, options.SortName);
Type tT = typeof(T);
PropertyInfo p = typeof(U).GetProperty(options.SortName);
Type funcType = typeof(Func<,>).MakeGenericType(tT, p.PropertyType);
LambdaExpression composition = Expression.Lambda(funcType, zm, z);
Type tQ = typeof(System.Linq.Queryable);
MethodInfo tQm = tQ.GetMethods(BindingFlags.Public | BindingFlags.Static).Single(z => z.Name == (options.SortOrder == SortOrder.Desc ? "OrderByDescending" : "OrderBy") && z.GetParameters().Count() == 2);
MethodInfo tQmg = tQm.MakeGenericMethod(tT, p.PropertyType);
var r = tQmg.Invoke(null, new object[] { source, composition });
return (IQueryable<T>)r;
}
}
Need to make the Where work with the compledProperty...
Example of use
IQueryable<ItemCategoryWithCount> data = db.ItemCategories.Join(db.ItemSpecifications, z => z.CategoryId, z => z.ItemCategoryId, (ItemCategory c, ItemSpecification s) => new { ItemCategory = c, Item = s })
.GroupBy(z => z.ItemCategory)
.Select(z => new { ItemCategory = z.Key, Count = z.Count() }) // Projection to anonymous type allows transpilation of Apply.
.Apply(options, z => z.ItemCategory)
.Select(z => new ItemCategoryWithCount(z.ItemCategory, z.Count))
;
Describe the solution you'd like
No response
Additional context
No response
Metadata
Metadata
Assignees
Labels
questionQuestion that needs to be answeredQuestion that needs to be answered