简体   繁体   English

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

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

I have a table Email which has a column EmailType .我有一个表格Email ,其中有一列EmailType EmailType is a enumeration in nHibernate and stored as int in DB. EmailTypeEmailType中的枚举,并以 int 形式存储在 DB 中。 I have extension method also to get name for the email type:我也有扩展方法来获取电子邮件类型的名称:

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;
        }
      }
    }
}

Then I can get name of the enum by using EmailType.PasswordReset.Name()然后我可以使用EmailType.PasswordReset.Name()获取枚举的名称

I am fetching list of Emails by creating nHibernate criteria:我通过创建 nHibernate 标准来获取电子邮件列表:

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

Problem with this is that it sorts rows with EmailType int stored in DB.问题在于它使用存储在 DB 中的 EmailType int 对行进行排序。 Is there any way I can use EmailType.PasswordReset.Name() extension method of EmailType enum to sort with the Name of enum?有什么方法可以使用EmailType.PasswordReset.Name()枚举的EmailType.PasswordReset.Name()扩展方法来EmailType枚举的名称进行排序?

As your enums (in this case) in alphabetical order would be represented by 2, 1, 0, you could order the EmailType in reverse order and this would give you what you want.由于按字母顺序排列的枚举(在本例中)将由 2、1、0 表示,因此您可以按相反的顺序对 EmailType 进行排序,这将为您提供所需的内容。

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

However, as you say, "this is a coincidence".然而,正如你所说,“这是一个巧合”。

The reason it can't sort on the enum names is that it doesn't know what they are, so you need to find a way to tell it.它无法对枚举名称进行排序的原因是它不知道它们是什么,因此您需要找到一种方法来告诉它。 There are two:有两种:

One way is to add a calculated field which converts the enum values into the names.一种方法是添加一个计算字段,将枚举值转换为名称。 I have done this with other databases and I belive @Formula is what you use in Hibernate.我已经用其他数据库完成了这个,我相信 @Formula 是你在 Hibernate 中使用的。

The other way is to create another table in your database which contains the enum numbers and enum values.另一种方法是在您的数据库中创建另一个包含枚举数字和枚举值的表。 Then link the two tables in the query so that the enum value is returned.然后链接查询中的两个表,以便返回枚举值。

In either case you apply the sort on the new field.无论哪种情况,您都可以在新字段上应用排序。

I faced the same issue and I found a way using projections我遇到了同样的问题,我找到了一种使用投影的方法

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

with

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);
}

(Here you can find more details on how the resulting SQL looks like: Adding more than one condition in Projection.Conditionals for queryover .) (您可以在此处找到有关结果 SQL 的更多详细信息:在 Projection.Conditionals 中为 queryover 添加多个条件。)

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

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