using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace CloudBuilder.Core.Extensions
{
///
/// 集合类型字符串排序操作类
///
/// 集合项类型
public static class CollectionPropertySorter
{
// ReSharper disable StaticFieldInGenericType
private static readonly ConcurrentDictionary Cache = new ConcurrentDictionary();
///
/// 按指定的属性名称对序列进行排序
///
/// 序列
/// 属性名称
/// 排序方向
public static IOrderedEnumerable OrderBy(IEnumerable source, string propertyName, ListSortDirection sortDirection)
{
propertyName.CheckNotNullOrEmpty("propertyName");
dynamic expression = GetKeySelector(propertyName);
dynamic keySelector = expression.Compile();
return sortDirection == ListSortDirection.Ascending
? Enumerable.OrderBy(source, keySelector)
: Enumerable.OrderByDescending(source, keySelector);
}
///
/// 按指定的属性名称对进行继续排序
///
/// 序列
/// 属性名称
/// 排序方向
public static IOrderedEnumerable ThenBy(IOrderedEnumerable source, string propertyName, ListSortDirection sortDirection)
{
propertyName.CheckNotNullOrEmpty("propertyName");
dynamic expression = GetKeySelector(propertyName);
dynamic keySelector = expression.Compile();
return sortDirection == ListSortDirection.Ascending
? Enumerable.ThenBy(source, keySelector)
: Enumerable.ThenByDescending(source, keySelector);
}
///
/// 按指定的属性名称对序列进行排序
///
/// IQueryable{T}序列
/// 属性名称
/// 排序方向
///
public static IOrderedQueryable OrderBy(IQueryable source, string propertyName, ListSortDirection sortDirection)
{
propertyName.CheckNotNullOrEmpty("propertyName");
dynamic keySelector = GetKeySelector(propertyName);
return sortDirection == ListSortDirection.Ascending
? Queryable.OrderBy(source, keySelector)
: Queryable.OrderByDescending(source, keySelector);
}
///
/// 按指定的属性名称对序列进行排序
///
/// IOrderedQueryable{T}序列
/// 属性名称
/// 排序方向
///
public static IOrderedQueryable ThenBy(IOrderedQueryable source, string propertyName, ListSortDirection sortDirection)
{
propertyName.CheckNotNullOrEmpty("propertyName");
dynamic keySelector = GetKeySelector(propertyName);
return sortDirection == ListSortDirection.Ascending
? Queryable.ThenBy(source, keySelector)
: Queryable.ThenByDescending(source, keySelector);
}
private static LambdaExpression GetKeySelector(string keyName)
{
Type type = typeof(T);
string key = type.FullName + "." + keyName;
if (Cache.ContainsKey(key))
{
return Cache[key];
}
ParameterExpression param = Expression.Parameter(type);
string[] propertyNames = keyName.Split('.');
Expression propertyAccess = param;
foreach (string propertyName in propertyNames)
{
PropertyInfo property = type.GetProperty(propertyName);
if (property == null)
{
throw new Exception(string.Format("指定对象中不存在名称为“{0}”的属性。", propertyName));
}
type = property.PropertyType;
propertyAccess = Expression.MakeMemberAccess(propertyAccess, property);
}
LambdaExpression keySelector = Expression.Lambda(propertyAccess, param);
Cache[key] = keySelector;
return keySelector;
}
}
}