470 lines
23 KiB
C#
470 lines
23 KiB
C#
|
|
using System.Collections.Generic;
|
|||
|
|
using System.Collections.Specialized;
|
|||
|
|
using System.Linq.Expressions;
|
|||
|
|
using System.Reflection;
|
|||
|
|
|
|||
|
|
namespace System.Linq
|
|||
|
|
{
|
|||
|
|
public static class LinqExtensions
|
|||
|
|
{
|
|||
|
|
/// <summary>通过页面控件动态构建查询</summary>
|
|||
|
|
public static IQueryable<TSource> WhereDynamic<TSource>(this IQueryable<TSource> source,
|
|||
|
|
NameValueCollection nameValues) where TSource : class
|
|||
|
|
{
|
|||
|
|
if (nameValues.Count > 0)
|
|||
|
|
{
|
|||
|
|
//构建 c=>Body中的c
|
|||
|
|
ParameterExpression param = Expression.Parameter(typeof(TSource), "c");
|
|||
|
|
//构建c=>Body中的Body
|
|||
|
|
var body = GetExpressoinBody(param, nameValues);
|
|||
|
|
if (body != null)
|
|||
|
|
{
|
|||
|
|
//将二者拼为c=>Body
|
|||
|
|
var expression = Expression.Lambda<Func<TSource, bool>>(body, param);
|
|||
|
|
//传到Where中当做参数,类型为Expression<Func<T,bool>>
|
|||
|
|
return source.Where(expression);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return source;
|
|||
|
|
}
|
|||
|
|
/// <summary>构建body</summary>
|
|||
|
|
private static Expression GetExpressoinBody(ParameterExpression param, NameValueCollection nameValues)
|
|||
|
|
{
|
|||
|
|
var list = new List<Expression>();
|
|||
|
|
if (nameValues.Count > 0)
|
|||
|
|
{
|
|||
|
|
var plist = param.Type.GetRuntimeProperties().ToDictionary(z => z.Name);//可以加缓存改善性能
|
|||
|
|
foreach (var item in nameValues.AllKeys)
|
|||
|
|
if (item.EndsWith(">") || item.EndsWith(">="))//可能大小查询
|
|||
|
|
{
|
|||
|
|
bool isEqual = item.EndsWith(">=");
|
|||
|
|
string key = isEqual ? item.TrimEnd('=').TrimEnd('>') : item.TrimEnd('>');
|
|||
|
|
if (!plist.ContainsKey(key) || nameValues[item].Length <= 0) continue;
|
|||
|
|
var rType = plist[key].GetMethod.ReturnType;
|
|||
|
|
if (rType == typeof(string)) continue;
|
|||
|
|
var e1 = Expression.Property(param, key);
|
|||
|
|
object dValue;
|
|||
|
|
if (TryParser(nameValues[item], rType, out dValue))
|
|||
|
|
//list.Add(Expression.GreaterThan(e1, Expression.Constant(dValue, rType)));
|
|||
|
|
list.Add(AddGreaterGreaterThan(e1, Expression.Constant(dValue, rType), isEqual));
|
|||
|
|
else if (plist[key].GetMethod.ReturnType.GenericTypeArguments.Count() > 0 && TryParser(nameValues[item], plist[key].GetMethod.ReturnType.GenericTypeArguments[0], out dValue))
|
|||
|
|
//list.Add(Expression.GreaterThan(e1, Expression.Constant(dValue, rType)));
|
|||
|
|
list.Add(AddGreaterGreaterThan(e1, Expression.Constant(dValue, rType), isEqual));
|
|||
|
|
else if (rType == typeof(DateTime?))
|
|||
|
|
{
|
|||
|
|
DateTime enddate = nameValues[item].ToDateTime().GetValueOrDefault();
|
|||
|
|
//list.Add(Expression.GreaterThan(e1, Expression.Constant(enddate, typeof(DateTime?))));
|
|||
|
|
list.Add(AddGreaterGreaterThan(e1, Expression.Constant(enddate, typeof(DateTime?)), isEqual));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else if (item.EndsWith("<") || item.EndsWith("<="))//可能大小查询
|
|||
|
|
{
|
|||
|
|
bool isEqual = item.EndsWith("<=");
|
|||
|
|
string key = isEqual ? item.TrimEnd('=').TrimEnd('<') : item.TrimEnd('<');
|
|||
|
|
if (!plist.ContainsKey(key) || nameValues[item].Length <= 0) continue;
|
|||
|
|
var rType = plist[key].GetMethod.ReturnType;
|
|||
|
|
if (rType == typeof(string)) continue;
|
|||
|
|
var e1 = Expression.Property(param, key);
|
|||
|
|
object dValue;
|
|||
|
|
if (TryParser(nameValues[item], rType, out dValue))
|
|||
|
|
{
|
|||
|
|
if (rType == typeof(DateTime)) dValue = ((DateTime)dValue).AddDays(1);
|
|||
|
|
//list.Add(Expression.LessThan(e1, Expression.Constant(dValue, rType)));
|
|||
|
|
list.Add(AddGreaterLessThan(e1, Expression.Constant(dValue, rType), isEqual));
|
|||
|
|
}
|
|||
|
|
else if (plist[key].GetMethod.ReturnType.GenericTypeArguments.Count() > 0 && TryParser(nameValues[item], plist[key].GetMethod.ReturnType.GenericTypeArguments[0], out dValue))
|
|||
|
|
{
|
|||
|
|
if (plist[key].GetMethod.ReturnType.GenericTypeArguments[0] == typeof(DateTime)) dValue = ((DateTime)dValue).AddDays(1);
|
|||
|
|
//list.Add(Expression.LessThan(e1, Expression.Constant(dValue, rType)));
|
|||
|
|
list.Add(AddGreaterLessThan(e1, Expression.Constant(dValue, rType), isEqual));
|
|||
|
|
}
|
|||
|
|
else if (rType == typeof(DateTime?))
|
|||
|
|
{
|
|||
|
|
DateTime enddate = nameValues[item].ToDateTime().GetValueOrDefault().AddDays(1);
|
|||
|
|
//list.Add(Expression.LessThan(e1, Expression.Constant(enddate, typeof(DateTime?))));
|
|||
|
|
list.Add(AddGreaterLessThan(e1, Expression.Constant(enddate, typeof(DateTime?)), isEqual));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else if (plist.ContainsKey(item) && nameValues[item].Length > 0)
|
|||
|
|
{
|
|||
|
|
var e1 = Expression.Property(param, item);
|
|||
|
|
var rType = plist[item].GetMethod.ReturnType;
|
|||
|
|
if (rType == typeof(string))//可能是like查询
|
|||
|
|
{
|
|||
|
|
var value = nameValues[item].Trim('%');
|
|||
|
|
var e2 = Expression.Constant(value, rType);
|
|||
|
|
if (nameValues[item].StartsWith("%") && nameValues[item].EndsWith("%"))
|
|||
|
|
list.Add(Expression.Call(e1, "Contains", null, new Expression[] { e2 }));
|
|||
|
|
else if (nameValues[item].StartsWith("%"))
|
|||
|
|
list.Add(Expression.Call(e1, "EndsWith", null, new Expression[] { e2 }));
|
|||
|
|
else if (nameValues[item].EndsWith("%"))
|
|||
|
|
list.Add(Expression.Call(e1, "StartsWith", null, new Expression[] { e2 }));
|
|||
|
|
else
|
|||
|
|
list.Add(Expression.Equal(e1, e2));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
else if (nameValues[item].IndexOf(",") > 0)//可能是in查询
|
|||
|
|
{
|
|||
|
|
if (rType == typeof(short))
|
|||
|
|
{
|
|||
|
|
var searchList = TryParser<short>(nameValues[item]);
|
|||
|
|
if (searchList.Any())
|
|||
|
|
list.Add(Expression.Call(Expression.Constant(searchList, rType), "Contains", null, new Expression[] { e1 }));
|
|||
|
|
}
|
|||
|
|
else if (rType == typeof(int))
|
|||
|
|
{
|
|||
|
|
var searchList = TryParser<int>(nameValues[item]);
|
|||
|
|
if (searchList.Any())
|
|||
|
|
list.Add(Expression.Call(Expression.Constant(searchList, rType), "Contains", null, new Expression[] { e1 }));
|
|||
|
|
}
|
|||
|
|
else if (rType == typeof(long))
|
|||
|
|
{
|
|||
|
|
var searchList = TryParser<long>(nameValues[item]);
|
|||
|
|
if (searchList.Any())
|
|||
|
|
list.Add(Expression.Call(Expression.Constant(searchList, rType), "Contains", null, new Expression[] { e1 }));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
object dValue;
|
|||
|
|
if (TryParser(nameValues[item], rType, out dValue))
|
|||
|
|
list.Add(Expression.Equal(e1, Expression.Constant(dValue, rType)));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return list.Count > 0 ? list.Aggregate(Expression.AndAlso) : null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private static List<T> TryParser<T>(string value)
|
|||
|
|
{
|
|||
|
|
string[] searchArray = value.Split(',');
|
|||
|
|
List<T> dList = new List<T>();
|
|||
|
|
foreach (var l in searchArray)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
T dValue = (T)Convert.ChangeType(l, typeof(T));
|
|||
|
|
dList.Add(dValue);
|
|||
|
|
}
|
|||
|
|
catch { }
|
|||
|
|
}
|
|||
|
|
return dList;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private static bool TryParser(string value, Type outType, out object dValue)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
dValue = Convert.ChangeType(value, outType);
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
catch
|
|||
|
|
{
|
|||
|
|
dValue = null;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//大于
|
|||
|
|
private static Expression AddGreaterGreaterThan(Expression exleft, Expression exright, bool Equal)
|
|||
|
|
{
|
|||
|
|
if (Equal)
|
|||
|
|
{
|
|||
|
|
return Expression.GreaterThanOrEqual(exleft, exright);
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
return Expression.GreaterThan(exleft, exright);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//大于
|
|||
|
|
private static Expression AddGreaterLessThan(Expression exleft, Expression exright, bool Equal)
|
|||
|
|
{
|
|||
|
|
if (Equal)
|
|||
|
|
{
|
|||
|
|
return Expression.LessThanOrEqual(exleft, exright);
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
return Expression.LessThan(exleft, exright);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 从 System.Collections.Generic.IQueryable`1 创建一个 System.Collections.Generic.List`1。并在集合末尾添加一个默认值为空的TSource实例
|
|||
|
|
/// </summary>
|
|||
|
|
/// <typeparam name="TSource">source 中的元素的类型。</typeparam>
|
|||
|
|
/// <param name="source">要从其创建 System.Collections.Generic.List`1 的 System.Collections.Generic.IEnumerable`1。</param>
|
|||
|
|
/// <returns>一个包含输入序列中元素的 System.Collections.Generic.List`1。</returns>
|
|||
|
|
public static List<TSource> ToListAndAddEmpty<TSource>(this IQueryable<TSource> source) where TSource : class
|
|||
|
|
{
|
|||
|
|
List<TSource> list = source.ToList();
|
|||
|
|
TSource addmodel = Activator.CreateInstance<TSource>();
|
|||
|
|
list.Add(addmodel);
|
|||
|
|
return list;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 从 System.Collections.Generic.IEnumerable`1 创建一个 System.Collections.Generic.List`1。并在集合末尾添加一个默认值为空的TSource实例
|
|||
|
|
/// </summary>
|
|||
|
|
/// <typeparam name="TSource">source 中的元素的类型。</typeparam>
|
|||
|
|
/// <param name="source">要从其创建 System.Collections.Generic.List`1 的 System.Collections.Generic.IEnumerable`1。</param>
|
|||
|
|
/// <returns>一个包含输入序列中元素的 System.Collections.Generic.List`1。</returns>
|
|||
|
|
public static List<TSource> ToListAndAddEmpty<TSource>(this IEnumerable<TSource> source) where TSource : class
|
|||
|
|
{
|
|||
|
|
List<TSource> list = source.ToList();
|
|||
|
|
TSource addmodel = Activator.CreateInstance<TSource>();
|
|||
|
|
list.Add(addmodel);
|
|||
|
|
return list;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 动态模糊查询
|
|||
|
|
/// </summary>
|
|||
|
|
/// <typeparam name="TSource">source 中的元素的类型。</typeparam>
|
|||
|
|
/// <param name="source">一个要模糊查找的值序列。</param>
|
|||
|
|
/// <typeparam name="TKey">由 keySelector 表示的函数返回的键类型。</typeparam>
|
|||
|
|
/// <param name="keyword">查询关键字(动态模糊在首或尾部添加%)</param>
|
|||
|
|
/// <param name="keyfiled">查询字段</param>
|
|||
|
|
/// <param name="keySelector">查询字段Lamvda表达式(支持多表导航查询)</param>
|
|||
|
|
/// <returns>一个 System.Linq.IOrderedQueryable`1,根据键对其元素模糊查找。</returns>
|
|||
|
|
public static IQueryable<TSource> LikeQueryable<TSource, TKey>(this IQueryable<TSource> source, string keyword, params Expression<Func<TSource, TKey>>[] keySelector)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
var paramT = Expression.Parameter(typeof(TSource), "c");//c=>
|
|||
|
|
Expression body = null;
|
|||
|
|
var list = new List<Expression>();
|
|||
|
|
foreach (var item in keySelector)
|
|||
|
|
{
|
|||
|
|
string[] paramKs = item.Body.ToString().Split('.');
|
|||
|
|
var e1 = Expression.Property(paramT, paramKs[1]);//c.user
|
|||
|
|
for (int i = 2; i < paramKs.Count(); i++)
|
|||
|
|
{
|
|||
|
|
e1 = Expression.Property(e1, paramKs[i]);//c.user.ID
|
|||
|
|
}
|
|||
|
|
if (e1.Type == typeof(string))
|
|||
|
|
{
|
|||
|
|
var value = keyword.Trim('%');
|
|||
|
|
var e2 = Expression.Constant(value, typeof(string));
|
|||
|
|
if (keyword.StartsWith("%") && keyword.EndsWith("%"))
|
|||
|
|
list.Add(Expression.Call(e1, "Contains", null, new Expression[] { e2 }));
|
|||
|
|
else if (keyword.StartsWith("%"))
|
|||
|
|
list.Add(Expression.Call(e1, "EndsWith", null, new Expression[] { e2 }));
|
|||
|
|
else if (keyword.EndsWith("%"))
|
|||
|
|
list.Add(Expression.Call(e1, "StartsWith", null, new Expression[] { e2 }));
|
|||
|
|
else
|
|||
|
|
list.Add(Expression.Equal(e1, e2));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
body = list.Count > 0 ? list.Aggregate(Expression.OrElse) : null;
|
|||
|
|
//构建c=>Body中的Body
|
|||
|
|
if (body != null)
|
|||
|
|
{
|
|||
|
|
//将二者拼为c=>Body
|
|||
|
|
var expression = Expression.Lambda<Func<TSource, bool>>(body, paramT);
|
|||
|
|
//传到Where中当做参数,类型为Expression<Func<T,bool>>
|
|||
|
|
source = source.Where(expression);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
catch
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
return source;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 动态模糊查询
|
|||
|
|
/// </summary>
|
|||
|
|
/// <typeparam name="TSource">source 中的元素的类型。</typeparam>
|
|||
|
|
/// <param name="source">一个要模糊查找的值序列。</param>
|
|||
|
|
/// <param name="keyword">查询关键字(动态模糊在首或尾部添加%)</param>
|
|||
|
|
/// <param name="keyfiled">查询字段</param>
|
|||
|
|
/// <param name="keySelector">查询字段Lamvda表达式(支持多表导航查询)</param>
|
|||
|
|
/// <returns>一个 System.Linq.IOrderedQueryable`1,根据键对其元素模糊查找。</returns>
|
|||
|
|
public static IQueryable<TSource> LikeQueryable<TSource>(this IQueryable<TSource> source, string keyword, params string[] keyfiled)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
var paramT = Expression.Parameter(typeof(TSource), "c");//c=>
|
|||
|
|
Expression body = null;
|
|||
|
|
var list = new List<Expression>();
|
|||
|
|
foreach (var item in keyfiled)
|
|||
|
|
{
|
|||
|
|
string[] paramKs = item.Split('.');
|
|||
|
|
var e1 = Expression.Property(paramT, paramKs[0]);//c.user
|
|||
|
|
for (int i = 1; i < paramKs.Count(); i++)
|
|||
|
|
{
|
|||
|
|
e1 = Expression.Property(e1, paramKs[i]);//c.user.ID
|
|||
|
|
}
|
|||
|
|
if (e1.Type == typeof(string))
|
|||
|
|
{
|
|||
|
|
var value = keyword.Trim('%');
|
|||
|
|
var e2 = Expression.Constant(value, typeof(string));
|
|||
|
|
if (keyword.StartsWith("%") && keyword.EndsWith("%"))
|
|||
|
|
list.Add(Expression.Call(e1, "Contains", null, new Expression[] { e2 }));
|
|||
|
|
else if (keyword.StartsWith("%"))
|
|||
|
|
list.Add(Expression.Call(e1, "EndsWith", null, new Expression[] { e2 }));
|
|||
|
|
else if (keyword.EndsWith("%"))
|
|||
|
|
list.Add(Expression.Call(e1, "StartsWith", null, new Expression[] { e2 }));
|
|||
|
|
else
|
|||
|
|
list.Add(Expression.Equal(e1, e2));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
body = list.Count > 0 ? list.Aggregate(Expression.OrElse) : null;
|
|||
|
|
//构建c=>Body中的Body
|
|||
|
|
if (body != null)
|
|||
|
|
{
|
|||
|
|
//将二者拼为c=>Body
|
|||
|
|
var expression = Expression.Lambda<Func<TSource, bool>>(body, paramT);
|
|||
|
|
//传到Where中当做参数,类型为Expression<Func<T,bool>>
|
|||
|
|
source = source.Where(expression);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
catch
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
return source;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 外键表动态模糊查询
|
|||
|
|
/// </summary>
|
|||
|
|
/// <typeparam name="TSource">source 中的元素的类型。</typeparam>
|
|||
|
|
/// <param name="source">一个要模糊查找的值序列。</param>
|
|||
|
|
/// <typeparam name="TKey">由 keySelector 表示的函数返回的键类型。</typeparam>
|
|||
|
|
/// <param name="keyword">查询关键字(动态模糊在首或尾部添加%)</param>
|
|||
|
|
/// <param name="keyfiledn">查询字段</param>
|
|||
|
|
/// <param name="keySelector">查询字段Lamvda表达式(支持多表导航查询)</param>
|
|||
|
|
/// <returns>一个 System.Linq.IOrderedQueryable`1,根据键对其元素模糊查找。</returns>
|
|||
|
|
public static IQueryable<TSource> LikeQueryable<TSource, TKey>(this IQueryable<TSource> source, string keyword, string keyfiled, params Expression<Func<TSource, TKey>>[] keySelector)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
var paramT = Expression.Parameter(typeof(TSource), "c");//c=>
|
|||
|
|
Expression body = null;
|
|||
|
|
var list = new List<Expression>();
|
|||
|
|
foreach (var item in keySelector)
|
|||
|
|
{
|
|||
|
|
string[] paramKs = item.Body.ToString().Split('.');
|
|||
|
|
var e1 = Expression.Property(paramT, paramKs[1]);//c.user
|
|||
|
|
for (int i = 2; i < paramKs.Count(); i++)
|
|||
|
|
{
|
|||
|
|
e1 = Expression.Property(e1, paramKs[i]);//c.user.ID
|
|||
|
|
}
|
|||
|
|
e1 = Expression.Property(e1, keyfiled);//c.user.ID
|
|||
|
|
if (e1.Type == typeof(string))
|
|||
|
|
{
|
|||
|
|
var value = keyword.Trim('%');
|
|||
|
|
var e2 = Expression.Constant(value, typeof(string));
|
|||
|
|
if (keyword.StartsWith("%") && keyword.EndsWith("%"))
|
|||
|
|
list.Add(Expression.Call(e1, "Contains", null, new Expression[] { e2 }));
|
|||
|
|
else if (keyword.StartsWith("%"))
|
|||
|
|
list.Add(Expression.Call(e1, "EndsWith", null, new Expression[] { e2 }));
|
|||
|
|
else if (keyword.EndsWith("%"))
|
|||
|
|
list.Add(Expression.Call(e1, "StartsWith", null, new Expression[] { e2 }));
|
|||
|
|
else
|
|||
|
|
list.Add(Expression.Equal(e1, e2));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
body = list.Count > 0 ? list.Aggregate(Expression.OrElse) : null;
|
|||
|
|
//构建c=>Body中的Body
|
|||
|
|
if (body != null)
|
|||
|
|
{
|
|||
|
|
//将二者拼为c=>Body
|
|||
|
|
var expression = Expression.Lambda<Func<TSource, bool>>(body, paramT);
|
|||
|
|
//传到Where中当做参数,类型为Expression<Func<T,bool>>
|
|||
|
|
source = source.Where(expression);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
catch
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
return source;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 动态排序
|
|||
|
|
/// </summary>
|
|||
|
|
/// <typeparam name="TSource">source 中的元素的类型。</typeparam>
|
|||
|
|
/// <param name="source">一个要排序查找的值序列。</param>
|
|||
|
|
/// <param name="keyfiled">排序字段</param>
|
|||
|
|
/// <param name="type">排序类型0不排序,1升序,2降序</param>
|
|||
|
|
/// <returns>一个 System.Linq.IOrderedQueryable`1,根据键对其元素模糊查找。</returns>
|
|||
|
|
public static IQueryable<TSource> OrderByQueryable<TSource>(this IQueryable<TSource> source, string keyfiled, int type)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
if (type == 0) return source;//不排序
|
|||
|
|
var paramT = Expression.Parameter(typeof(TSource), "c");//c=>
|
|||
|
|
string[] paramKs = keyfiled.Split('.');
|
|||
|
|
var e1 = Expression.Property(paramT, paramKs[0]);//c.user
|
|||
|
|
for (int i = 1; i < paramKs.Count(); i++)
|
|||
|
|
{
|
|||
|
|
e1 = Expression.Property(e1, paramKs[i]);//c.user.ID
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
dynamic expression = Expression.Lambda(e1, paramT);
|
|||
|
|
|
|||
|
|
switch (type)
|
|||
|
|
{
|
|||
|
|
case 1:
|
|||
|
|
source = Queryable.OrderBy(source, expression);
|
|||
|
|
break;
|
|||
|
|
case 2:
|
|||
|
|
source = Queryable.OrderByDescending(source, expression);
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
catch
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
return source;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 动态排序
|
|||
|
|
/// </summary>
|
|||
|
|
/// <typeparam name="TSource">source 中的元素的类型。</typeparam>
|
|||
|
|
/// <param name="source">一个要排序查找的值序列。</param>
|
|||
|
|
/// <param name="keyfiled">排序字段</param>
|
|||
|
|
/// <param name="type">排序类型0不排序,1升序,2降序</param>
|
|||
|
|
/// <returns>一个 System.Linq.IOrderedQueryable`1,根据键对其元素模糊查找。</returns>
|
|||
|
|
public static IEnumerable<TSource> OrderByQueryable<TSource>(this IEnumerable<TSource> source, string keyfiled, int type)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
if (type == 0) return source;//不排序
|
|||
|
|
var paramT = Expression.Parameter(typeof(TSource), "c");//c=>
|
|||
|
|
string[] paramKs = keyfiled.Split('.');
|
|||
|
|
var e1 = Expression.Property(paramT, paramKs[0]);//c.user
|
|||
|
|
for (int i = 1; i < paramKs.Count(); i++)
|
|||
|
|
{
|
|||
|
|
e1 = Expression.Property(e1, paramKs[i]);//c.user.ID
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
dynamic expression = Expression.Lambda(e1, paramT);
|
|||
|
|
|
|||
|
|
switch (type)
|
|||
|
|
{
|
|||
|
|
case 1:
|
|||
|
|
source = Queryable.OrderBy(source.AsQueryable(), expression);
|
|||
|
|
break;
|
|||
|
|
case 2:
|
|||
|
|
source = Queryable.OrderByDescending(source.AsQueryable(), expression);
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
catch
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
return source;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|