0

假设我有一个包含状态类型的类,它被定义为这样的枚举:

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

现在设置已经完成,我的困境是:

在我的存储库类中,我想通过 Status 属性对所有 MyObject 实体进行排序,nHibernate 将其保留为 int。但是,由于我无法控制的权力,我无法重新排序 MyStatusEnum 以便枚举值按字母顺序排序。当我创建条件以选择 MyObjects 列表并尝试按 Status 属性对其进行排序时,它会按 Status 的 int 值进行排序。

    ICriteria criteria = this.Session.CreateCriteria<MyObject>("obj")
        .AddOrder(Order.Asc("Status"))
        .List()

我真的很希望能够按枚举名称订购。任何想法将不胜感激。

4

2 回答 2

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 ,您将其设置为等于枚举中当前状态的相对位置,并仅按该字段排序(您可以对其进行索引)。

另一种选择是在您的类上定义一个公式属性(即在映射中指定一个公式),其中该公式指定一个值以根据状态进行排序。

于 2012-06-15T15:47:32.197 回答
0

简单的方法是简单地重构您的枚举,以便值和名称具有相同的顺序:

public enum MyStatusEnum
{
    Active = 1,
    Paused = 3,
    Completed = 2
}

但是您始终可以使用List.Sort 方法来完成这项工作:

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 不知道这些名称。

除非您将枚举存储为字符串,就像在这个 SO Question中讨论的那样,否则您唯一的选择是在“内存中”而不是在数据库中执行排序。

于 2012-06-14T00:37:43.983 回答