首页 新闻 会员 周边

Expression.Lambda 如何将Type类型转为泛型

1
悬赏园豆:100 [已解决问题] 解决于 2022-12-20 17:07

主要目的,就是将字符串的查询条件,转为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);
}
天星轮回的主页 天星轮回 | 初学一级 | 园豆:94
提问于:2022-12-15 14:08
< >
分享
最佳答案
0

typeof(TKey) 不是可以获取类型吗?

收获园豆:100
dudu | 高人七级 |园豆:30994 | 2022-12-15 16:10

是反过来的,通过Type生成TKey
或者换个说法,我只有一个Type,怎么调用泛型方法

天星轮回 | 园豆:94 (初学一级) | 2022-12-15 17:37
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册