文章转载自:https://www.cnblogs.com/Extnet/p/9848272.html
前端采用Datatable插件生成的table,自带的排序请求,发送到后台例如: title asc ,此时需要把字符串转换成efccore的查询排序方式,因此完成动态生成orderby。这样可以根据前端传的字段来动态排序了。
调用方式:
await data.OrderBy(order[0], order[1] == "desc").Skip(page).Take(limit).ToListAsync().ConfigureAwait(false);
以下是生成方法
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
namespace Flyinghat.Common.Extensions
{
public static class LinqExtensions
{
public static IQueryable<T> OrderBy<T>(this IQueryable<T> query, string field, bool desc)
{
if (!string.IsNullOrWhiteSpace(field))
{
ParameterExpression p = Expression.Parameter(typeof(T));
Expression key = Expression.Property(p, field);
var propInfo = GetPropertyInfo(typeof(T), field);
var expr = GetOrderExpression(typeof(T), propInfo);
if (desc)
{
var method = typeof(Queryable).GetMethods().FirstOrDefault(m => m.Name == "OrderByDescending" && m.GetParameters().Length == 2);
var genericMethod = method.MakeGenericMethod(typeof(T), propInfo.PropertyType);
return (IQueryable<T>)genericMethod.Invoke(null, new object[] { query, expr });
}
else
{
var method = typeof(Queryable).GetMethods().FirstOrDefault(m => m.Name == "OrderBy" && m.GetParameters().Length == 2);
var genericMethod = method.MakeGenericMethod(typeof(T), propInfo.PropertyType);
return (IQueryable<T>)genericMethod.Invoke(null, new object[] { query, expr });
}
}
return query;
}
/// <summary>
/// 获取反射
/// </summary>
/// <param name="objType"></param>
/// <param name="name"></param>
/// <returns></returns>
private static PropertyInfo GetPropertyInfo(Type objType, string name)
{
var properties = objType.GetProperties();
var matchedProperty = properties.FirstOrDefault(p => p.Name.Equals(name, StringComparison.OrdinalIgnoreCase));
if (matchedProperty == null)
throw new ArgumentException("对象不包含指定属性名");
return matchedProperty;
}
/// <summary>
/// 获取生成表达式
/// </summary>
/// <param name="objType"></param>
/// <param name="pi"></param>
/// <returns></returns>
private static LambdaExpression GetOrderExpression(Type objType, PropertyInfo pi)
{
var paramExpr = Expression.Parameter(objType);
var propAccess = Expression.PropertyOrField(paramExpr, pi.Name);
var expr = Expression.Lambda(propAccess, paramExpr);
return expr;
}
}
}