在Linq中使用SwitchExpression到实体的OrderBy

OrderBy with SwitchExpression in Linq to entities
2020-10-22
  •  译文(汉语)
  •  原文(英语)

我需要对枚举进行自定义orderby.我尝试使用SwitchExpression:

public static IQueryable<T> MyOrderByEnum<T>(this IQueryable<T> source, string propName, Type enumType)
    {
        var type = typeof (T);
        var property = type.GetProperty(propName);
        var parameter = Expression.Parameter(type, "p");
        var propertyAccess = Expression.Property(parameter, property);

        var enumValues = Enum.GetValues(enumType);
        var switchCases = new SwitchCase[enumValues.Length];
        int i = 0;
        foreach (var val in enumValues)
        {
            switchCases[i] = Expression.SwitchCase(
                Expression.Constant(val.ToDisplay()),
                Expression.Constant(val)
                );
            i++;
        }

        var switchExpr1 =
            Expression.Switch(
                propertyAccess,
                Expression.Constant(""),
                switchCases
                );

        var orderByExp1 = Expression.Lambda(switchExpr1, parameter);
        MethodCallExpression resultExp = Expression.Call(typeof (Queryable), "OrderBy", new[] {type, orderByExp1.Body.Type}, source.Expression, orderByExp1);
        return (IOrderedQueryable<T>) source.Provider.CreateQuery(resultExp);
    }

但是当我执行

filtered.MyOrderBy("field1", typeof(FieldState)).ToList();

我得到错误:

类型'Switch'的未知LINQ表达式.

还有另一种方法可以使订单表达式转换为sql构造"CASE WHEN ..."吗?

解决过程1

尝试Expression.Condition(https://msdn.microsoft.com/zh-cn/library/bb340500%28v=vs.110%29.aspx)我认为如果在匿名投影中使用,它会转换为CASE

I need make custom orderby for enum. I try use SwitchExpression:

public static IQueryable<T> MyOrderByEnum<T>(this IQueryable<T> source, string propName, Type enumType)
    {
        var type = typeof (T);
        var property = type.GetProperty(propName);
        var parameter = Expression.Parameter(type, "p");
        var propertyAccess = Expression.Property(parameter, property);

        var enumValues = Enum.GetValues(enumType);
        var switchCases = new SwitchCase[enumValues.Length];
        int i = 0;
        foreach (var val in enumValues)
        {
            switchCases[i] = Expression.SwitchCase(
                Expression.Constant(val.ToDisplay()),
                Expression.Constant(val)
                );
            i++;
        }

        var switchExpr1 =
            Expression.Switch(
                propertyAccess,
                Expression.Constant(""),
                switchCases
                );

        var orderByExp1 = Expression.Lambda(switchExpr1, parameter);
        MethodCallExpression resultExp = Expression.Call(typeof (Queryable), "OrderBy", new[] {type, orderByExp1.Body.Type}, source.Expression, orderByExp1);
        return (IOrderedQueryable<T>) source.Provider.CreateQuery(resultExp);
    }

But when I execute

filtered.MyOrderBy("field1", typeof(FieldState)).ToList();

I get error:

Unknown LINQ expression of type 'Switch'.

Is there another way to make order expression that will translate into sql construction "CASE WHEN ..."?

Solutions1

Try Expression.Condition (https://msdn.microsoft.com/en-us/library/bb340500%28v=vs.110%29.aspx) I think that translates to CASE When if used in an anonymous projection

转载于:https://stackoverflow.com/questions/30577134/orderby-with-switchexpression-in-linq-to-entities

本人是.net程序员,因为英语不行,使用工具翻译,希望对有需要的人有所帮助
如果本文质量不好,还请谅解,毕竟这些操作还是比较费时的,英语较好的可以看原文

留言回复
我们只提供高质量资源,素材,源码,坚持 下了就能用 原则,让客户花了钱觉得值
上班时间 : 周一至周五9:00-17:30 期待您的加入