我有一张表Email
,其中有一列EmailType
。 EmailType
是nHibernate中的枚举,在DB中存储为int。我还有扩展方法来获取电子邮件类型的名称:
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
扩展方法对枚举名称进行排序吗?
答案 0 :(得分:0)
由于您的枚举(在本例中)按字母顺序排列将由2,1,0表示,您可以按相反的顺序订购EmailType,这样可以为您提供所需的内容。
criteria.AddOrder(Order.desc("EmailType"));
然而,正如你所说,&#34;这是巧合&#34;。
它无法对枚举名称进行排序的原因是它不知道它们是什么,因此您需要找到一种方法来表达它。有两个:
一种方法是添加一个计算字段,将枚举值转换为名称。我已经用其他数据库做了这个,我相信@Formula就是你在Hibernate中使用的。
另一种方法是在数据库中创建另一个包含枚举数和枚举值的表。然后链接查询中的两个表,以便返回枚举值。
在任何一种情况下,您都会对新字段应用排序。
答案 1 :(得分:0)
我遇到了同样的问题,我找到了一种使用投影的方法
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 的更多详细信息:Adding more than one condition in Projection.Conditionals for queryover。)