using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace Ropin.Inspection.Repository
{
internal static class LinqExtensions
{
private static PropertyInfo GetPropertyInfo(Type objType, string name)
{
var properties = objType.GetProperties();
var matchedProperty = properties.FirstOrDefault(p => p.Name == name);
if (matchedProperty == null)
{
throw new ArgumentException("name");
}
return matchedProperty;
}
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;
}
///
/// 多个OrderBy用逗号隔开,属性前面带-号表示反序排序,exp:"name,-createtime"
///
///
///
///
///
public static IEnumerable OrderByBatch(this IEnumerable query, string name)
{
var index = 0;
var a = name.Split(',');
foreach (var item in a)
{
var m = index++ > 0 ? "ThenBy" : "OrderBy";
if (item.StartsWith("-"))
{
m += "Descending";
name = item.Substring(1);
}
else
{
name = item;
}
name = name.Trim();
var propInfo = GetPropertyInfo(typeof(T), name);
var expr = GetOrderExpression(typeof(T), propInfo);
var method = typeof(Enumerable).GetMethods().FirstOrDefault(mt => mt.Name == m && mt.GetParameters().Length == 2);
var genericMethod = method.MakeGenericMethod(typeof(T), propInfo.PropertyType);
query = (IEnumerable)genericMethod.Invoke(null, new object[] { query, expr.Compile() });
}
return query;
}
///
/// 多个OrderBy用逗号隔开,属性前面带-号表示反序排序,exp:"name,-createtime"
///
///
///
///
///
public static IQueryable OrderByBatch(this IQueryable query, string name)
{
var index = 0;
var a = name.Split(',');
foreach (var item in a)
{
var m = index++ > 0 ? "ThenBy" : "OrderBy";
if (item.StartsWith("-"))
{
m += "Descending";
name = item.Substring(1);
}
else
{
name = item;
}
name = name.Trim();
var propInfo = GetPropertyInfo(typeof(T), name);
var expr = GetOrderExpression(typeof(T), propInfo);
var method = typeof(Queryable).GetMethods().FirstOrDefault(mt => mt.Name == m && mt.GetParameters().Length == 2);
var genericMethod = method.MakeGenericMethod(typeof(T), propInfo.PropertyType);
query = (IQueryable)genericMethod.Invoke(null, new object[] { query, expr });
}
return query;
}
///
/// 正序排序单个
///
///
///
///
///
public static IQueryable OrderBy(this IQueryable query, string name)
{
var propInfo = GetPropertyInfo(typeof(T), name);
var expr = GetOrderExpression(typeof(T), propInfo);
var method = typeof(Queryable).GetMethods().FirstOrDefault(m => m.Name == "OrderBy" && m.GetParameters().Length == 2);
var genericMethod = method.MakeGenericMethod(typeof(T), propInfo.PropertyType);
return (IQueryable)genericMethod.Invoke(null, new object[] { query, expr });
}
///
/// 正序排序单个(非首个)
///
///
///
///
///
public static IQueryable ThenBy(this IQueryable query, string name)
{
var propInfo = GetPropertyInfo(typeof(T), name);
var expr = GetOrderExpression(typeof(T), propInfo);
var method = typeof(Queryable).GetMethods().FirstOrDefault(m => m.Name == "ThenBy" && m.GetParameters().Length == 2);
var genericMethod = method.MakeGenericMethod(typeof(T), propInfo.PropertyType);
return (IQueryable)genericMethod.Invoke(null, new object[] { query, expr });
}
///
/// 反序排序单个
///
///
///
///
///
public static IQueryable OrderByDescending(this IQueryable query, string name)
{
var propInfo = GetPropertyInfo(typeof(T), name);
var expr = GetOrderExpression(typeof(T), propInfo);
var metMethods = typeof(Queryable).GetMethods();
var method = metMethods.FirstOrDefault(m => m.Name == "OrderByDescending" && m.GetParameters().Length == 2);
var genericMethod = method.MakeGenericMethod(typeof(T), propInfo.PropertyType);
return (IQueryable)genericMethod.Invoke(null, new object[] { query, expr });
}
///
/// 反序排序单个(非首个)
///
///
///
///
///
public static IQueryable ThenByDescending(this IQueryable query, string name)
{
var propInfo = GetPropertyInfo(typeof(T), name);
var expr = GetOrderExpression(typeof(T), propInfo);
var metMethods = typeof(Queryable).GetMethods();
var method = metMethods.FirstOrDefault(m => m.Name == "ThenByDescending" && m.GetParameters().Length == 2);
var genericMethod = method.MakeGenericMethod(typeof(T), propInfo.PropertyType);
return (IQueryable)genericMethod.Invoke(null, new object[] { query, expr });
}
}
}