假设我有一个包含状态类型的类,它被定义为枚举,如下所示:
public class MyObject
{
public virtual int Id { get; set; }
public virtual SomeEntity Data { get; set; }
public virtual MyStatusEnum Status { get; set; }
}
public enum MyStatusEnum
{
Active = 1,
Paused = 2,
Completed = 3
}
我通过Fluent nHibernate完成的映射如下所示:
public class MyObjectMap: ClassMap<MyObject>
{
public MyObjectMap()
{
this.Table("my_object_table");
...
this.References(x => x.SomeEntity).Column("some_entity_id").Not.Nullable();
this.Map(x => x.Status).Column("status_type").CustomType<MyStatusEnum>().Not.Nullable();
}
}
既然设置已经完成,我的困境就是:
在我的repository类中,我想通过Status属性对所有MyObject实体进行排序,nHibernate将其作为int保留。但是,由于我无法控制的功能,我无法重新排序MyStatusEnum,以便按字母顺序排列枚举值。当我创建我的条件以选择MyObjects列表,并尝试按Status属性对其进行排序时,它按Status的int值排序。
ICriteria criteria = this.Session.CreateCriteria<MyObject>("obj")
.AddOrder(Order.Asc("Status"))
.List()
我真的希望能够通过枚举名称进行排序。任何想法都将不胜感激。
答案 0 :(得分:1)
如果要在数据库中对其进行排序,则必须按照带有case语句的投影进行排序,但这将无法使用索引,并且可能无法使用,具体取决于您的NHibernate版本(按不在选择中的投影进行排序时会出现错误。
这样的事可能有用:
.AddOrder(Order.Asc(
Projections.SqlProjection(
"CASE {alias}.Status "
+ "WHEN 1 THEN 0 "
+ "WHEN 2 THEN 3 "
+ "WHEN 3 THEN 2 END",
new string[0], new IType[0])))
另一个选项(更好的性能)是在类中添加一个属性,例如StatusOrder,你设置的属性等于枚举中当前状态的相对位置,然后按该字段排序(你可以索引)。
另一个选项是在类上定义一个公式属性(即在映射中指定一个公式),其中公式指定一个值,根据状态进行排序。
答案 1 :(得分:0)
简单的方法是简单地重构枚举,以便值和名称具有相同的顺序:
public enum MyStatusEnum
{
Active = 1,
Paused = 3,
Completed = 2
}
但你总是可以使用List.Sort method来完成这项工作:
enum MyEnum
{
Alpha,
Beta,
Gama
}
static void Main(string[] args)
{
List<MyEnum> list = new List<MyEnum>()
{
MyEnum.Gama,
MyEnum.Beta,
MyEnum.Alpha
};
list.Sort((x, y) => x.ToString().CompareTo(y.ToString()));
}
NHibernate根据数据库中存储的结果集对结果集进行排序。从你所说的我猜你的枚举被存储为整数,因此你将无法要求SQL Server按名称对它们进行排序,因为SQL Server不知道这些名称。
除非您将枚举存储为字符串,如this SO Question中所述,否则您唯一的选择就是在内存中执行排序,而不是在数据库中执行。