mh_frame_sps/APT.Infrastructure.Core/Extensions/QueryableOrderExtension.cs
2026-04-07 13:47:52 +08:00

58 lines
2.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics.Contracts;
namespace APT.Infrastructure.Core
{
public static class QueryableOrderExtension
{
public static IQueryable<T> SetQueryableOrder<T>(this IQueryable<T> query, string sort, string order, bool isThen = false)
{
if (string.IsNullOrEmpty(sort))
throw new Exception("必须指定排序字段!");
//PropertyInfo sortProperty = typeof(T).GetProperty(sort, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
//if (sortProperty == null)
// throw new Exception("查询对象中不存在排序字段" + sort + "");
ParameterExpression param = Expression.Parameter(typeof(T), "t");
Expression body = param;
if (Nullable.GetUnderlyingType(body.Type) != null)
body = Expression.Property(body, "Value");
body = GetPropertyLambdaExpression(body, sort);
LambdaExpression keySelectorLambda = Expression.Lambda(body, param);
if (string.IsNullOrEmpty(order))
order = "ASC";
string queryMethod = isThen ? order.ToUpper() == "DESC" ? "ThenByDescending" : "ThenBy" : order.ToUpper() == "DESC" ? "OrderByDescending" : "OrderBy";
query = query.Provider.CreateQuery<T>(Expression.Call(typeof(Queryable), queryMethod,
new Type[] { typeof(T), body.Type },
query.Expression,
Expression.Quote(keySelectorLambda)));
return query;
}
private static Expression GetPropertyLambdaExpression(Expression body, string fileName)
{
string[] propertyNames = fileName.Split('.');
Type type = body.Type;
foreach (string propertyName in propertyNames)
{
PropertyInfo property = type.GetProperty(propertyName);
//Contract.Assume(property != null);
if (property == null)
{
throw new Exception($"类型{type.Name}不存在属性{propertyName}");
}
type = property.PropertyType;
body = Expression.MakeMemberAccess(body, property);
}
return body;
}
}
}