主要目的,就是将字符串的查询条件,转为Lambda表达式。
而IQueryable的排序方法:public static IOrderedQueryable<TSource> OrderBy<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector);
这个表达式,是需要一个泛型的Key的,就是需要排序的那个属性的类型。
可是我只有Type,要怎么转为泛型使用?
下面是我写的方法,比较笨重,求助有没有更简单的。
// OrderBy = "UserId Desc"
public static IQueryable<TSource> OrderBy<TSource>(this IQueryable<TSource> source, string orderStr)
{
var orderStrArr = orderStr.ToListString();
foreach (var item in orderStrArr)
{
var itemArr = item.ToListString(false,' ');
var typeExp = Expression.Parameter(typeof(TSource), "s");
var proExp = Expression.Property(typeExp, itemArr.First());
if (itemArr.Count == 1)
{
source = source.OrderBy(typeExp, proExp);
}
else if (itemArr[1].ToLower() == "asc")
{
source = source.OrderBy(typeExp, proExp);
}
else
{
source = source.OrderBy(typeExp, proExp, false);
}
}
return source;
}
private static IOrderedQueryable<TSource> OrderBy<TSource>(this IQueryable<TSource> source, ParameterExpression typeExp, MemberExpression proExp,bool isASC = true)
{
var typeName = proExp.Type.GetNullableName();
switch (typeName)
{
case "Int32":
var lambdaExpInt = Expression.Lambda<Func<TSource, int>>(proExp, typeExp);
return OrderBy(source, lambdaExpInt, isASC);
case "Int32?":
var lambdaExpInt2 = Expression.Lambda<Func<TSource, int?>>(proExp, typeExp);
return OrderBy(source, lambdaExpInt2, isASC);
case "Int64":
var lambdaExpLong = Expression.Lambda<Func<TSource, long>>(proExp, typeExp);
return OrderBy(source, lambdaExpLong, isASC);
case "Int64?":
var lambdaExpLong2 = Expression.Lambda<Func<TSource, long?>>(proExp, typeExp);
return OrderBy(source, lambdaExpLong2, isASC);
case "String":
var lambdaExpString = Expression.Lambda<Func<TSource, string>>(proExp, typeExp);
return OrderBy(source, lambdaExpString, isASC);
case "DateTime":
var lambdaExpDateTime = Expression.Lambda<Func<TSource, DateTime>>(proExp, typeExp);
return OrderBy(source, lambdaExpDateTime, isASC);
case "DateTime?":
var lambdaExpDateTime2 = Expression.Lambda<Func<TSource, DateTime?>>(proExp, typeExp);
return OrderBy(source, lambdaExpDateTime2, isASC);
case "Guid":
var lambdaExpGuid = Expression.Lambda<Func<TSource, Guid>>(proExp, typeExp);
return OrderBy(source, lambdaExpGuid, isASC);
case "Guid?":
var lambdaExpGuid2 = Expression.Lambda<Func<TSource, Guid?>>(proExp, typeExp);
return OrderBy(source, lambdaExpGuid2, isASC);
case "Decimal":
var lambdaExpDecimal = Expression.Lambda<Func<TSource, decimal>>(proExp, typeExp);
return OrderBy(source, lambdaExpDecimal, isASC);
case "Decimal?":
var lambdaExpDecimal2 = Expression.Lambda<Func<TSource, decimal?>>(proExp, typeExp);
return OrderBy(source, lambdaExpDecimal2, isASC);
default:
throw new Exception($"字符串转排序时,属性类型未识别:{proExp.Type.FullName}");
}
}
private static IOrderedQueryable<TSource> OrderBy<TSource,TKey>(IQueryable<TSource> source, Expression<Func<TSource, TKey>> lambda, bool isAsc)
{
return isAsc ? source.OrderBy(lambda) : source.OrderByDescending(lambda);
}
typeof(TKey)
不是可以获取类型吗?
是反过来的,通过Type生成TKey
或者换个说法,我只有一个Type,怎么调用泛型方法
@天星轮回: 参考园子里的博文: