【问题标题】:Entity Framework sort by Enum value alphabetically实体框架按字母顺序按枚举值排序
【发布时间】:2014-07-11 01:05:00
【问题描述】:

我有一个名为Comment 的实体,它有一个enum 类型为CommentType 的属性:

public class Comment
{
    public virtual Guid Id { get; private set; }
    public virtual CommentType CommentType { get; set; }
    // other prop removed for simplicity
}

public enum CommentType
{
    Comment,
    Correction,
    Improvement,
    BugFix,
    NewFeauture,
    Other 
}

我需要通过CommentType 枚举的alphabetically 值从数据库中选择 cmets,类似于

_db.Comments.OrderBy(p => p.CommentType)

但是,Enum 值被视为整数,因此无法按字母顺序正确排序。

有什么方法可以将一些属性/元数据添加到 Enum 值以使它们按字母顺序正确排序?

一种解决方案是将整数值分配给枚举值,但我已经有许多需要更新的数据库记录。而且这种解决方案不适合新添加的枚举值。

public enum CommentType
{
    Comment = 2,
    Correction = 3,
    Improvement = 4,
    BugFix = 1,
    NewFeauture = 5,
    Other = 6 
}

【问题讨论】:

  • 尝试使用p => p.CommentType.ToString()
  • @DoanCuong,要完成这项工作,您必须首先调用 _db.Comments.ToList(),就像下面提到的 Machet。否则会导致运行时错误。

标签: asp.net entity-framework sorting enums linq-to-entities


【解决方案1】:

目前您的枚举名称在数据库级别未知,因此我认为您有两种选择。

  1. 在服务器端使用值:

    _db.Comments.ToList().OrderBy(p => p.CommentType.ToString())
    
  2. 在数据库端添加值:您应该创建包含注释类型名称的表。然后您可以在 cmets 和 commentTypeNames 之间创建外键并使用简单的选择:

    _db.Comments.OrderBy(c => c.CommentTypeNames.Name)
    

    或者只是加入:

    _db.Comments
        .Join(
            _db.CommentTypeNames, 
            c => c.CommentType, 
            ctn => ctn.CommentType,
            (c, ctn) => new { Comment = c, CommentName = ctn })
        .OrderBy(g => g.CommentName.Name)
        .Select(g => g.Comment);
    
  3. 还有计算列。我从来没有使用过这些,所以我没有经验。也许您可以添加将由数据库上的 CASE 语句解析为字符串的列。但是我不确定这将如何影响性能/可维护性。欲了解更多信息,您可以查看http://geekswithblogs.net/DavidPaquette/archive/2012/09/23/calculated-columns-in-entity-framework-code-first-migrations.aspx

出于性能原因,我建议采用选项 2,最好在数据库中执行此类操作。

我假设您首先使用代码,所以这篇文章可能对您有所帮助:EF5 Code First Enums and Lookup Tables

【讨论】:

  • 我希望有一个属性,EntityFramework 可以根据值优先解释和发送特定订单
  • @RaraituL 我怀疑是否存在这样的属性。我在答案中添加了有关计算列的简短信息,也许会对您有所帮助
  • 对于方法 1:要使其工作,您必须先调用 ToList(),如果您有大量记录,这是不现实的,因为排序发生在代码中,而不是在数据库中。
【解决方案2】:

这种表格的想法当然很好,尤其是当枚举有很多值并且很可能得到新值时。但是,当添加枚举值时,代码和数据库都需要维护。 一般来说,当枚举是 volatile 时,我不会使用枚举,而只使用表。 但是当它不太可能发生太大变化时,您也可以考虑坚持使用枚举,只需写出订单指令:

_db.Comments.OrderBy(p => 
    p.CommentType == CommentType.Comment ? "Comment" :
    p.CommentType == CommentType.Correction ? "Correction" :
    p.CommentType == CommentType.Improvement? "Improvement" :
    .... :
    "ZZZ")

【讨论】:

    【解决方案3】:

    作为替代方案,您可以将Comment 类中的CommentType 属性转换为指向CommentType(Id, Name) 表的外键“CommentTypeId”,其中包含您的Id 值和相应的文本名称。

    这将使您可以轻松地按文本订购。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-06-11
      • 1970-01-01
      • 1970-01-01
      • 2016-08-20
      • 1970-01-01
      • 1970-01-01
      • 2012-04-13
      相关资源
      最近更新 更多