繁体   English   中英

如何使用枚举类型的显示名称对 nHibernate 中的枚举列进行排序

[英]How to sort enum column in nHibernate with display name of enum type

我有一个表格Email ,其中有一列EmailType EmailTypeEmailType中的枚举,并以 int 形式存储在 DB 中。 我也有扩展方法来获取电子邮件类型的名称:

namespace Email
{
    public enum EmailType : int
    {
        PasswordReset = 0,
        EmailVerification = 1,
        AccountCreation = 2
    };

    public static class EmailType Extension
    {
      public static string Name(this EmailType self)
      {
        switch (self)
        {
          case EmailType.PasswordReset :
            return "Password Reset";
          case EmailType.EmailVerification :
            return "Email Verification";
          case EmailType.AccountCreation :
            return "Account Creation";
          default:
            return null;
        }
      }
    }
}

然后我可以使用EmailType.PasswordReset.Name()获取枚举的名称

我通过创建 nHibernate 标准来获取电子邮件列表:

var criteria = session.CreateCriteria<Email>();
criteria.SetFirstResult(startIndex).SetMaxResults(maxResults);
criteria.AddOrder(Order.Asc("EmailType"));
return criteria.List<Email>();

问题在于它使用存储在 DB 中的 EmailType int 对行进行排序。 有什么方法可以使用EmailType.PasswordReset.Name()枚举的EmailType.PasswordReset.Name()扩展方法来EmailType枚举的名称进行排序?

由于按字母顺序排列的枚举(在本例中)将由 2、1、0 表示,因此您可以按相反的顺序对 EmailType 进行排序,这将为您提供所需的内容。

criteria.AddOrder(Order.desc("EmailType"));

然而,正如你所说,“这是一个巧合”。

它无法对枚举名称进行排序的原因是它不知道它们是什么,因此您需要找到一种方法来告诉它。 有两种:

一种方法是添加一个计算字段,将枚举值转换为名称。 我已经用其他数据库完成了这个,我相信 @Formula 是你在 Hibernate 中使用的。

另一种方法是在您的数据库中创建另一个包含枚举数字和枚举值的表。 然后链接查询中的两个表,以便返回枚举值。

无论哪种情况,您都可以在新字段上应用排序。

我遇到了同样的问题,我找到了一种使用投影的方法

QueryOver<TRoot, TSubType>.OrderBy(IProjection projection)

queryOver
    .OrderBy(GetOrderByEnumProjection<TSubType, MyEnum>(x => x.EnumProperty, GetAllMyEnumValuesSortedByDisplayName(CultureInfo.CurrentCulture)));

private static IProjection GetOrderByEnumProjection<TObject, TEnum>(Expression<Func<TObject, object>> enumProperty, IReadOnlyList<TEnum> enumValues)
    where TEnum : Enum
{
    int index = enumValues.Count - 1;

    TEnum enumValue = enumValues[index];

    IProjection elseProjection = GetConditional(enumProperty, enumValue, index, Projections.Constant(-1));

    for (index = enumValues.Count - 2; index >= 0; index--)
    {
        enumValue = enumValues[index];

        elseProjection = GetConditional(enumProperty, enumValue, index, elseProjection);
    }

    return elseProjection;
}

private static IProjection GetConditional<TObject, TEnum>(Expression<Func<TObject, object>> enumProperty, TEnum value, int sortIndex, IProjection elseProjection)
    where TEnum : Enum
{
    return Projections.Conditional(
        Restrictions.Eq(Projections.Property<TObject>(enumProperty), value),
        Projections.Constant(sortIndex),
        elseProjection);
}

(您可以在此处找到有关结果 SQL 的更多详细信息:在 Projection.Conditionals 中为 queryover 添加多个条件。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM