基于静态值对实体排序的Linq表达式

本文关键字:排序 实体 Linq 表达式 于静态 静态 | 更新日期: 2023-09-27 18:15:00

我正在做一个ASP。. NET MVC项目首先使用EF代码,我需要构建一个Linq expression,以便根据静态字典值订购Item实体。

public partial class Item
{
    public enum TypeE
    {
        Type1,
        Type2,
        Type3,
        Type4,
    }
    public TypeE Type { get; set; } // Mapped database column
    public static Dictionary<TypeE, int> MyDic = new Dictionary<TypeE, int>()
    {
        { TypeE.Type1, 42 },
        { TypeE.Type2, 16 },
        { TypeE.Type3, 0 },
        { TypeE.Type4, 34 },
    };
}

我的最终目标是在Linq to entities中工作的一些方法,这将允许我实现类似myEntities.OrderBy(i => Item.MyDic[i.Type])的东西。

我必须精确地说,我不能使用AsEnumerable()或其他任何枚举实体集合,我真的需要直接在Linq to entities中工作的东西。
我也想避免在数据库中创建参考表,我真的在寻找一个Linq expression .

几天前,我问了一个非常类似的问题,关于如何通过枚举描述对实体进行排序,Ivan Stoev (https://stackoverflow.com/a/40203664/2828106)给出的答案完美地实现了我想要的。
如果有一种方法可以将这种逻辑用于新的目的,那就太好了,但是我没有足够的实验,在尝试的时候我最终得到了一个无限循环。

基于静态值对实体排序的Linq表达式

下面是对dictionary使用的相同方法:

public static class Expressions
{
    public static Expression<Func<TSource, int>> DictionaryOrder<TSource, TKey, TOrder>(Expression<Func<TSource, TKey>> source, IReadOnlyDictionary<TKey, TOrder> by)
    {
        var body = by
            .OrderBy(entry => entry.Value)
            .Select((entry, ordinal) => new { entry.Key, ordinal })
            .Reverse()
            .Aggregate((Expression)null, (next, item) => next == null ? (Expression)
                Expression.Constant(item.ordinal) :
                Expression.Condition(
                    Expression.Equal(source.Body, Expression.Constant(item.Key)),
                    Expression.Constant(item.ordinal),
                    next));
        return Expression.Lambda<Func<TSource, int>>(body, source.Parameters[0]);
    }
}

和示例用法:

var order = Expressions.DictionaryOrder((Item x) => x.Type, Item.MyDic);