簡體   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