按枚举描述排序

2023-11-24

我正在开发一个首先使用 EF 代码的 ASP.NET MVC 项目,我面临着需要通过枚举描述进行排序的情况:

public partial class Item
{
    public enum MyEnumE
    {
        [Description("description of enum1")]
        Enum1,
        [Description("description of enum2")]
        Enum2,
        ...
    }

    public MyEnumE MyEnum { get; set; }
}

这里是Search and SortAndPaginate功能:

public async Task<IPagedList<Item>> Search(ItemCriteria criteria, SortableTypeE sortName, SortOrder.TypeE sortOrder, int pageNb)
    {
        var itemFilter = GenerateFilter(criteria);
        var items = entities.Items.Where(itemFilter);

        return await SortAndPaginate(items, sortName, sortOrder, pageNb);
    }

    private async Task<IPagedList<Item>> SortAndPaginate(IQueryable<Item> items, SortableTypeE sortName, SortOrder.TypeE sortOrder, int pageNb)
    {
        IOrderedQueryable<Item> result = null;

        switch (sortName)
        {
            ...
            case SortableTypeE.Type:
                result = sortOrder == SortOrder.TypeE.ASC
                    ? items.OrderBy(i => i.MyEnum.GetDescription())
                    : items.OrderByDescending(i => i.MyEnum.GetDescription());
                result = result.ThenBy(i => i.SomeOtherProperty);
                break;
            ...
        }

        if (result != null)
        {
            return await result.ToPagedListAsync(pageNb, 10);
        }

        return PagedListHelper.Empty<Item>();
    }

问题是Item桌子可能相当大。
我想过打电话ToListAsync就在之后entities.Items.Where(itemFilter)但这将返回所有过滤的项目,尽管我只需要一页。听起来不是一个好主意。

但如果我不这样做EF不会知道GetDescription()方法,我只能想到两个解决方案:
- 将我的数据库列更改为字符串(枚举描述)而不是枚举本身(但对我来说听起来像是黑客)
- 或按字母顺序排列MyEnumE组件直接在enum声明(看起来很脏而且也很难维护)

我很困惑,因为我担心打电话时的表现ToListAsync过滤后,所有其他解决方案看起来都很脏,我绝对需要一个IPagedList从返回的Search method.

有人知道如何处理这个问题吗?

多谢。

UPDATE

这里是GetDescription方法(如有需要可以更改):

public static string GetDescription(this Enum e)
{
    FieldInfo fi = e.GetType().GetField(e.ToString());
    DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
    if (attributes.Length > 0)
        return attributes[0].Description;
    else
        return e.ToString();
}

解决方案

我最终会采纳 Ivan Stoev 的建议,因为我的项目主要基于Linq (using Linq而不是存储过程等),因此该解决方案似乎比创建引用表更适合我的特定情况。

However Niyoko Yuliawan's and Michael Freidgeim对我来说也是很好的答案,任何阅读这篇文章并拥有更多数据库方法的人都应该寻求他们的解决方案;)

非常感谢大家。


我会选择动态表达。它更灵活,可以轻松更改,而不会影响数据库表和查询​​。

但是,我不是按数据库中的描述字符串进行排序,而是在内存中创建有序映射,将int每个枚举值的“order”值如下:

public static class EnumHelper
{
    public static Expression<Func<TSource, int>> DescriptionOrder<TSource, TEnum>(this Expression<Func<TSource, TEnum>> source)
        where TEnum : struct
    {
        var enumType = typeof(TEnum);
        if (!enumType.IsEnum) throw new InvalidOperationException();

        var body = ((TEnum[])Enum.GetValues(enumType))
            .OrderBy(value => value.GetDescription())
            .Select((value, ordinal) => new { value, ordinal })
            .Reverse()
            .Aggregate((Expression)null, (next, item) => next == null ? (Expression)
                Expression.Constant(item.ordinal) :
                Expression.Condition(
                    Expression.Equal(source.Body, Expression.Constant(item.value)),
                    Expression.Constant(item.ordinal),
                    next));

        return Expression.Lambda<Func<TSource, int>>(body, source.Parameters[0]);
    }

    public static string GetDescription<TEnum>(this TEnum value)
        where TEnum : struct
    {
        var enumType = typeof(TEnum);
        if (!enumType.IsEnum) throw new InvalidOperationException();

        var name = Enum.GetName(enumType, value);
        var field = typeof(TEnum).GetField(name, BindingFlags.Static | BindingFlags.Public);
        return field.GetCustomAttribute<DescriptionAttribute>()?.Description ?? name;
    }
}

用法如下:

case SortableTypeE.Type:
    var order = EnumHelper.DescriptionOrder((Item x) => x.MyEnum);
    result = sortOrder == SortOrder.TypeE.ASC
        ? items.OrderBy(order)
        : items.OrderByDescending(order);
    result = result.ThenBy(i => i.SomeOtherProperty);
    break;

这会生成这样的表达式:

x => x.MyEnum == Enum[0] ? 0 :
     x.MyEnum == Enum[1] ? 1 :
     ...
     x.MyEnum == Enum[N-2] ? N - 2 :
     N - 1;

其中 0,1,..N-2 是按描述排序的值列表中的相应索引。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

按枚举描述排序 的相关文章

  • 如何在 Unity 中从 RenderTexture 访问原始数据

    问题的简短版本 我正在尝试访问 Unity 中 RenderTexture 的内容 我一直在使用 Graphics Blit 使用自己的材质进行绘制 Graphics Blit null renderTexture material 我的材
  • SSH 主机密钥指纹与模式 C# WinSCP 不匹配

    我尝试通过 WinSCP 使用 C 连接到 FTPS 服务器 但收到此错误 SSH 主机密钥指纹 与模式不匹配 经过大量研究 我相信这与密钥的长度有关 当使用 服务器和协议信息 下的界面进行连接时 我从 WinSCP 获得的密钥是xx xx
  • 如何在 WPF RichTextBox 中跟踪 TextPointer?

    我正在尝试了解 WPF RichTextBox 中的 TextPointer 类 我希望能够跟踪它们 以便我可以将信息与文本中的区域相关联 我目前正在使用一个非常简单的示例来尝试弄清楚发生了什么 在 PreviewKeyDown 事件中 我
  • 使用 C# 在 WinRT 中获取可用磁盘空间

    DllImport kernel32 dll SetLastError true static extern bool GetDiskFreeSpaceEx string lpDirectoryName out ulong lpFreeBy
  • 使用 Google Analytics API 在 C# 中显示信息

    我一整天都在寻找一个好的解决方案 但谷歌发展得太快了 我找不到有效的解决方案 我想做的是 我有一个 Web 应用程序 它有一个管理部分 用户需要登录才能查看信息 在本节中 我想显示来自 GA 的一些数据 例如某些特定网址的综合浏览量 因为我
  • c 中的错误:声明隐藏了全局范围内的变量

    当我尝试编译以下代码时 我收到此错误消息 错误 声明隐藏了全局范围内的变量 无效迭代器 节点 根 我不明白我到底在哪里隐藏或隐藏了之前声明的全局变量 我怎样才能解决这个问题 typedef node typedef struct node
  • C# 用数组封送结构体

    假设我有一个类似于 public struct MyStruct public float a 我想用一些自定义数组大小实例化一个这样的结构 在本例中假设为 2 然后我将其封送到字节数组中 MyStruct s new MyStruct s
  • 在 ASP.Net Core 2.0 中导出到 Excel

    我曾经使用下面的代码在 ASP NET MVC 中将数据导出到 Excel Response AppendHeader content disposition attachment filename ExportedHtml xls Res
  • 编译的表达式树会泄漏吗?

    根据我的理解 JIT 代码在程序运行时永远不会从内存中释放 这是否意味着重复调用 Compile 表达式树上会泄漏内存吗 这意味着仅在静态构造函数中编译表达式树或以其他方式缓存它们 这可能不那么简单 正确的 他们可能是GCed Lambda
  • Windows 10 中 Qt 桌面应用程序的缩放不当

    我正在为 Windows 10 编写一个简单的 Qt Widgets Gui 应用程序 我使用的是 Qt 5 6 0 beta 版本 我遇到的问题是它根本无法缩放到我的 Surfacebook 的屏幕上 这有点难以判断 因为 SO 缩放了图
  • 实体框架 - 选择特定列并返回强类型而不丢失强制类型转换

    我正在尝试做类似的事情这个帖子 https stackoverflow com questions 1094931 linq to sql how to select specific columns and return strongly
  • 网络参考共享类

    我用 Java 编写了一些 SOAP Web 服务 在 JBoss 5 1 上运行 其中两个共享一个类 AddressTO Web 服务在我的 ApplycationServer 上正确部署 一切都很顺利 直到我尝试在我的 C 客户端中使用
  • 用 C 实现 Unix shell:检查文件是否可执行

    我正在努力用 C 语言实现 Unix shell 目前正在处理相对路径的问题 特别是在输入命令时 现在 我每次都必须输入可执行文件的完整路径 而我宁愿简单地输入 ls 或 cat 我已经设法获取 PATH 环境变量 我的想法是在 字符处拆分
  • 可空属性与可空局部变量

    我对以下行为感到困惑Nullable types class TestClass public int value 0 TestClass test new TestClass Now Nullable GetUnderlyingType
  • AccessViolationException 未处理

    我正在尝试使用史蒂夫 桑德森的博客文章 http blog stevensanderson com 2010 01 28 editing a variable length list aspnet mvc 2 style 为了在我的 ASP
  • 检查 url 是否指向文件或页面

    我们需要以下内容 如果文件确实是文件 则从 URL 下载该文件 否则 如果它是一个页面 则什么也不做 举个简单的例子 我有以下命令来下载文件 My Computer Network DownloadFile http www wired c
  • char指针或char变量的默认值是什么[重复]

    这个问题在这里已经有答案了 下面是我尝试打印 char 变量和指针的默认值 值的代码 但无法在控制台上看到它 它是否有默认值或只是无法读取 ASCII 范围 include
  • 如何在单击按钮时重新绑定 igGrid igniteUI 控件中的数据?

    我在 ASP NET MVC3 应用程序中使用 Infragistics Ignite UI 控件 我有一个已绑定到 客户 数据的网格 工作正常 现在我有按钮了 单击后我会进行 ajax 调用 在控制器中 我编写了仅选择 客户 数据的一部分
  • GDK3/GTK3窗口更新的精确定时

    我有一个使用 GTK 用 C 语言编写的应用程序 尽管该语言对于这个问题可能并不重要 这个应用程序有全屏gtk window与单个gtk drawing area 对于绘图区域 我已经通过注册了一个刻度回调gtk widget add ti
  • 更改显示的 DPI 缩放大小使 Qt 应用程序的字体大小渲染得更大

    我使用 Qt 创建了一些 GUI 应用程序 我的 GUI 应用程序包含按钮和单选按钮等控件 当我运行应用程序时 按钮内的按钮和字体看起来正常 当我将显示器的 DPI 缩放大小从 100 更改为 150 或 200 时 无论分辨率如何 控件的

随机推荐

  • C# 泛型继承和协变第 2 部分

    这是我的原始线程 C 泛型继承和协变 仅在我的只读界面上 我希望继承起作用 public delegate Boolean EnumerateItemsDelegate
  • 包包含同名的对象和包

    我在使用 Maven 或 Eclipse 编译一些 Scala 时遇到问题 我尝试从包含命名空间和同名类的 Java jar 导入一个类 我可以编译scalac 然而 例如 Java 项目 jar 包含 src foo bar java s
  • 如何在 Node.js Web 应用程序中管理 MongoDB 连接?

    我正在使用节点 mongodb native用MongoDB驱动写一个网站 我对如何管理连接有一些疑问 仅使用一个 MongoDB 连接来处理所有请求是否足够 是否存在任何性能问题 如果没有 我可以设置一个全局连接以在整个应用程序中使用吗
  • Xcode 4.2 无法调试 iOS 4.2.1 (8C148)

    我最近更新到 Xcode 4 2 我还将我的新 iPad 2 和 iPod 最新一代 更新到了 iOS 5 我构建了我的应用程序并且可以毫无问题地调试它们 我运行 iOS 4 2 1 8C148 的旧版 iPod 无法运行 也没有出现任何错
  • Firebase BigQuery 服务器偏移时间

    背景 我正在将 Firebase 分析数据导出到 BigQuery 我正在使用 cron 作业来处理 BigQuery 中的数据以获得洞察力 Problem 为了能够只处理增量数据 即自上次运行 cron 作业以来到达的数据 我需要一种方法
  • .htaccess URL 重写挑战

    我在某些 URL 重写方面遇到问题 下面的所有内容都工作正常 但我需要添加一条从 URL 中删除查询字符串的规则 site com page a b会变成site com page 有人可以帮忙吗 我已经阅读了一些关于 htaccess 的
  • 如何在Nuxt SSR模式下更改页面的URL而不重新加载整个页面?

    我正在尝试构建一个主详细信息视图 其中列表和详细信息在桌面上并排显示 但在移动设备上的不同页面上显示 如下图所示 我的列表中可能有 500 到 10000 个项目要显示 我用 10000 个项目模拟了这两种方法 请随意更改 server a
  • 如何使用 Java 类运行 Hadoop?

    我正在关注这本书Hadoop 权威指南 我对示例 3 1 感到困惑 有一个 Java 源文件 URLCat java 我用javac将其编译为 URLCat class 然后使用jar把它包进罐子里 书上说要用 hadoop URLCat
  • 使用 PyEphem 计算阴影长度

    我正在使用 PyEphem 并想要计算阴影的长度 假设一根单位长度的棍子种植在地上 长度由 cot phi 给出 其中 phi 是太阳高度角 如果我错了 请纠正我 我不知道在太阳上使用什么场 在下面的示例中 我使用角度 alt import
  • Freemarker 中的默认转义

    在 Freemarker 模板中 我们可以使用 escape 指令自动将转义应用于包含的块内的所有插值 lt escape x as x html gt lt name is escaped as html gt Hallo name 有没
  • 在 Python 3 中使用 urllib 的套接字资源警告

    我正在使用 urllib request urlopen 从我正在尝试测试的网络服务中获取数据 这会返回一个 HTTPResponse 对象 然后我通过 read 来获取响应正文 但我总是在 socket py 中看到有关未关闭套接字的 R
  • 错误:请求的资源需要用户身份验证:在 AzureCLI 任务构建管道中

    我无法从 azureCLI 任务触发 azure 管道构建 Task task AzureCLI 2 inputs azureSubscription Free Trial My subscription scriptType pscore
  • 上下文或活动之外的 getString

    我找到了R string对于将硬编码字符串保留在我的代码之外来说非常棒 并且我想继续在实用程序类中使用它 该实用程序类与我的应用程序中的模型一起使用以生成输出 例如 在本例中 我从活动之外的模型生成一封电子邮件 是否可以使用getStrin
  • React Hooks:即使使用空数组作为参数,useEffect() 也会被调用两次

    我正在编写代码 以便在从数据库加载数据之前 它将显示加载消息 然后在加载后 使用加载的数据渲染组件 为此 我同时使用 useState 挂钩和 useEffect 挂钩 这是代码 问题是 当我检查 console log 时 useEffe
  • 向请求模块添加标头

    早些时候我用过httplib模块在请求中添加标头 现在我正在尝试同样的事情requests module 这是我正在使用的 python 请求模块 http pypi python org pypi requests 如何添加标题reque
  • PHP 无法使用 mkdir 创建目录

    我有一个以前工作的 PHP 脚本 可以使用以下命令创建目录mkdir webfolder var www html images user mkdir webfolder 0770 我对文件夹的权限设置做了一些更改 var www html
  • 在 Java 中使用 scala 映射

    我有两个文件 一种是scala 另一种是java Scala 文件有一个返回 scala 不可变映射的函数 Java 文件想要使用该映射作为字典 我是 scala 和 java 的新手 如何将该 scala 映射转换为 java 字典 这是
  • 关于懒惰 [ RAKU ]

    Raku 文档中指出 gather take 结构正在被延迟评估 在下面的例子中 我很难得出关于构造的惰性的结论 say Iterate to Infinity is 1 Inf WHAT say gather is gather take
  • 从asp.net获取AD用户objectGuid的身份验证

    我在 ASP NET 应用程序中使用 Windows 身份验证 我想知道如何最好地从当前登录的用户获取 objectGuid 问候 埃吉尔 建议的解决方案相当昂贵 更好的解决方案是使用 SID 来查找帐户 而不是通过域和用户名进行搜索 us
  • 按枚举描述排序

    我正在开发一个首先使用 EF 代码的 ASP NET MVC 项目 我面临着需要通过枚举描述进行排序的情况 public partial class Item public enum MyEnumE Description descript