orderby,注意字段是小写的,支持多个排序,比如id,name desc
framework/PasteApeart.Application/PasteApeart.Application.xml
diff --git a/framework/PasteApeart.Application/PasteApeart.Application.xml b/framework/PasteApeart.Application/PasteApeart.Application.xml
index dc54162..0aeaeec 100644
--- a/framework/PasteApeart.Application/PasteApeart.Application.xml
+++ b/framework/PasteApeart.Application/PasteApeart.Application.xml
@@ -1199,6 +1199,15 @@
<returns></returns>
<exception cref="T:PasteApeart.Application.Contracts.PasteCodeException"></exception>
</member>
+ <member name="M:PasteApeart.Application.PasteDefaultHelper.PasteOrder(System.Linq.IQueryable,System.String)">
+ <summary>
+ 支持多排序 比如id,name desc等
+ </summary>
+ <param name="query"></param>
+ <param name="ordering"></param>
+ <returns></returns>
+ <exception cref="T:System.ArgumentException"></exception>
+ </member>
<member name="M:PasteApeart.Application.PasteDefaultHelper.ReadCurrentPropertyThrowException(System.Type,System.String)">
<summary>
查找字段 应对new的情况
framework/PasteApeart.Application/PasteDefaultHelper.cs
diff --git a/framework/PasteApeart.Application/PasteDefaultHelper.cs b/framework/PasteApeart.Application/PasteDefaultHelper.cs
index 588293f..736db2f 100644
--- a/framework/PasteApeart.Application/PasteDefaultHelper.cs
+++ b/framework/PasteApeart.Application/PasteDefaultHelper.cs
@@ -2020,29 +2020,32 @@ namespace PasteApeart.Application
var actionOrderby = false;
if (!String.IsNullOrEmpty(orderby))
{
- //这里做查找和适配
- var fieldName = orderby.Split(" ")[0];
- var findOrderProperty = ReadCurrentProperty(entityType, fieldName);
- if (findOrderProperty != null)
- {
- var orderType = "OrderByDescending";
- if (!orderby.Contains(" desc", StringComparison.OrdinalIgnoreCase))
- {
- orderType = "OrderBy";
- }
- // 构建排序表达式 默认 OrderByDescending(x=>x.Id)
- var parameter = Expression.Parameter(entityType, "x");
- var propertyAccess = Expression.Property(parameter, findOrderProperty);
- var lambda = Expression.Lambda(propertyAccess, parameter);
- // 使用正确的属性类型作为排序键类型
- var orderByDescendingCall = Expression.Call(
- typeof(Queryable), orderType,
- new Type[] { entityType, findOrderProperty.PropertyType }, // 使用实际的属性类型
- query.Expression,
- lambda);
- query = query.Provider.CreateQuery(orderByDescendingCall);
- actionOrderby = true;
- }
+ #region 下面是旧版本,只支持单个排序
+ //var fieldName = orderby.Split(" ")[0];
+ //var findOrderProperty = ReadCurrentProperty(entityType, fieldName);
+ //if (findOrderProperty != null)
+ //{
+ // var orderType = "OrderByDescending";
+ // if (!orderby.Contains(" desc", StringComparison.OrdinalIgnoreCase))
+ // {
+ // orderType = "OrderBy";
+ // }
+ // // 构建排序表达式 默认 OrderByDescending(x=>x.Id)
+ // var parameter = Expression.Parameter(entityType, "x");
+ // var propertyAccess = Expression.Property(parameter, findOrderProperty);
+ // var lambda = Expression.Lambda(propertyAccess, parameter);
+ // // 使用正确的属性类型作为排序键类型
+ // var orderByDescendingCall = Expression.Call(
+ // typeof(Queryable), orderType,
+ // new Type[] { entityType, findOrderProperty.PropertyType }, // 使用实际的属性类型
+ // query.Expression,
+ // lambda);
+ // query = query.Provider.CreateQuery(orderByDescendingCall);
+ // actionOrderby = true;
+ //}
+ #endregion
+ //支持多个查询,比如id,name desc
+ query = PasteOrder(query, orderby);
}
if (!actionOrderby)
{
@@ -2065,6 +2068,75 @@ namespace PasteApeart.Application
}
/// <summary>
+ /// 支持多排序 比如id,name desc等
+ /// </summary>
+ /// <param name="query"></param>
+ /// <param name="ordering"></param>
+ /// <returns></returns>
+ /// <exception cref="ArgumentException"></exception>
+ private IOrderedQueryable PasteOrder(IQueryable query, string ordering)
+ {
+ //if (string.IsNullOrWhiteSpace(ordering))
+ //return query.OrderBy(x => 1);
+ if (String.IsNullOrEmpty(ordering))
+ {
+ return (IOrderedQueryable)query;
+ }
+ // 分割多个排序字段
+ var orderClauses = ordering.Split(',', StringSplitOptions.RemoveEmptyEntries);
+ IOrderedQueryable orderedQuery = null;
+ var eType = query.ElementType;
+ foreach (var clause in orderClauses)
+ {
+ var parts = clause.Trim().Split(' ', StringSplitOptions.RemoveEmptyEntries);
+ if (parts.Length == 0) continue;
+
+ var fieldName = parts[0];
+ var descending = false;
+ if (parts.Length > 1)
+ {
+ descending = parts.Length > 1 &&
+ (parts[1].Equals("desc", StringComparison.OrdinalIgnoreCase) ||
+ parts[1].Equals("descending", StringComparison.OrdinalIgnoreCase));
+ }
+ var propertyInfo = ReadTypeProperties(eType).FirstOrDefault(x => string.Equals(x.Name, fieldName, StringComparison.OrdinalIgnoreCase));
+ if (propertyInfo == null)
+ {
+ throw new ArgumentException($"类型 '{eType.Name}' 中不存在属性 '{fieldName}'");
+ }
+
+ // 构建表达式
+ var parameter = Expression.Parameter(eType, "x");
+ var property = Expression.Property(parameter, propertyInfo);
+ var lambda = Expression.Lambda(property, parameter);
+
+ if (orderedQuery == null)
+ {
+ // 第一个排序字段
+ var methodName = descending ? "OrderByDescending" : "OrderBy";
+ var methodCall = Expression.Call(
+ typeof(Queryable), methodName,
+ new Type[] { eType, property.Type },
+ query.Expression, Expression.Quote(lambda));
+
+ orderedQuery = (IOrderedQueryable)query.Provider.CreateQuery(methodCall);
+ }
+ else
+ {
+ // 后续排序字段
+ var methodName = descending ? "ThenByDescending" : "ThenBy";
+ var methodCall = Expression.Call(
+ typeof(Queryable), methodName,
+ new Type[] { eType, property.Type },
+ orderedQuery.Expression, Expression.Quote(lambda));
+
+ orderedQuery = (IOrderedQueryable)orderedQuery.Provider.CreateQuery(methodCall);
+ }
+ }
+ return orderedQuery ?? (IOrderedQueryable)query;
+ }
+
+ /// <summary>
/// 查找字段 应对new的情况
/// </summary>
/// <param name="entityType"></param>
framework/PasteApeart.Helper/PasteApeartAttribute.cs
diff --git a/framework/PasteApeart.Helper/PasteApeartAttribute.cs b/framework/PasteApeart.Helper/PasteApeartAttribute.cs
index a257709..cb9d5f6 100644
--- a/framework/PasteApeart.Helper/PasteApeartAttribute.cs
+++ b/framework/PasteApeart.Helper/PasteApeartAttribute.cs
@@ -2025,10 +2025,10 @@ namespace PasteApeart.Helper
{
/// <summary>
- /// 排序
+ /// 排序 不写表示当前字段的默认值,小写开头(ui要判断样式) 比如nickName和nickName desc
/// </summary>
- /// <param name="acsName">升序 示例:Id,不写默认为当前字段升序</param>
- /// <param name="descName">降序 示例:Id desc,不写为当前字段降序</param>
+ /// <param name="acsName">升序 示例:nickName,不写默认为当前字段升序</param>
+ /// <param name="descName">降序 示例:nickName desc,不写为当前字段降序</param>
public PasteOrderbyAttribute(string acsName = null, string descName = null)
{
base.Name = "orderby";
framework/PasteApeart.Helper/QueryableExtensions.cs
diff --git a/framework/PasteApeart.Helper/QueryableExtensions.cs b/framework/PasteApeart.Helper/QueryableExtensions.cs
index 0294c71..166227b 100644
--- a/framework/PasteApeart.Helper/QueryableExtensions.cs
+++ b/framework/PasteApeart.Helper/QueryableExtensions.cs
@@ -1,4 +1,4 @@
-using System.Linq.Expressions;
+using System.Linq.Expressions;
using System.Reflection;
namespace PasteApeart.Helper
@@ -42,16 +42,16 @@ namespace PasteApeart.Helper
//var property = Expression.Property(parameter, fieldName);
//var lambda = Expression.Lambda(property, parameter);
// 使用 GetProperty 而不是 Expression.Property
- var propertyInfo = eType.GetProperty(fieldName,
- BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.IgnoreCase);
-
- if (propertyInfo == null)
- {
- // 如果当前类型没有,查找基类的属性
- propertyInfo = eType.GetProperty(fieldName,
- BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
- }
-
+ //var propertyInfo = eType.GetProperty(fieldName,
+ // BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.IgnoreCase);
+
+ //if (propertyInfo == null)
+ //{
+ // // 如果当前类型没有,查找基类的属性
+ // propertyInfo = eType.GetProperty(fieldName,
+ // BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
+ //}
+ var propertyInfo = ReadTypeProperties(eType).FirstOrDefault(x => string.Equals(x.Name, fieldName, StringComparison.OrdinalIgnoreCase));
if (propertyInfo == null)
{
throw new ArgumentException($"类型 '{eType.Name}' 中不存在属性 '{fieldName}'");
@@ -129,15 +129,15 @@ namespace PasteApeart.Helper
//var lambda = Expression.Lambda(property, parameter);
// 使用 GetProperty 而不是 Expression.Property
- var propertyInfo = eType.GetProperty(fieldName,
- BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.IgnoreCase);
-
- if (propertyInfo == null)
- {
- // 如果当前类型没有,查找基类的属性
- propertyInfo = eType.GetProperty(fieldName,
- BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
- }
+ //var propertyInfo = eType.GetProperty(fieldName,
+ // BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.IgnoreCase);
+ var propertyInfo = ReadTypeProperties(eType).FirstOrDefault(x => string.Equals(x.Name, fieldName, StringComparison.OrdinalIgnoreCase));
+ //if (propertyInfo == null)
+ //{
+ // // 如果当前类型没有,查找基类的属性
+ // propertyInfo = eType.GetProperty(fieldName,
+ // BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
+ //}
if (propertyInfo == null)
{
@@ -175,5 +175,51 @@ namespace PasteApeart.Helper
return orderedQuery ?? (IOrderedQueryable)query;
}
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="searchType"></param>
+ /// <returns></returns>
+ private static PropertyInfo[] ReadTypeProperties(Type searchType)
+ {
+
+ var typeName = searchType.FullName;
+ // 使用GetOrCreate替代TryGetValue+Set
+ //return t.GetProperties(); // 耗时的反射操作
+ var allProperties = searchType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
+
+ // 如果有属性被隐藏(new),才需要复杂处理
+ var hasDuplicates = allProperties.Length != allProperties.Select(p => p.Name).Distinct().Count();
+ if (!hasDuplicates)
+ {
+ // 没有重复属性名,直接返回
+ return allProperties;
+ }
+ // 有重复属性名,进行分组处理
+ var propertyGroups = allProperties.GroupBy(p => p.Name);
+ var result = new PropertyInfo[propertyGroups.Count()];
+
+ int index = 0;
+ foreach (var group in propertyGroups)
+ {
+ // 手动查找,避免 LINQ 的开销
+ PropertyInfo selected = null;
+ foreach (var prop in group)
+ {
+ if (prop.DeclaringType == searchType)
+ {
+ selected = prop;
+ break; // 找到当前类声明的,立即退出
+ }
+ selected ??= prop; // 否则保留第一个
+ }
+ result[index++] = selected!;
+ }
+
+ return result;
+
+
+ }
}
}