如何在NHibernate中为关联指定排序条件?

时间:2010-01-06 00:10:13

标签: nhibernate

对于具有类型ParentEntity的集合的实体ChildEntity,其中包含类型为int的Order属性,如何使用按{{1}排序的子集合检索父实体} 特别是通过使用NHibernate docs here第12.4节中讨论的Criteria API?

我尝试使用类似以下的代码:

Order

不幸的是,这段代码产生了2个public ParentEntity GetById(int id) { ICriteria criteria = _sessionFactory.GetCurrentSession().CreateCriteria(typeof (ParentEntity)); criteria.Add(Restrictions.Eq("Id", id)) .CreateCriteria("Children") .AddOrder(Order.Desc("Order")); return (ParentEntity) criteria.List()[0]; } 语句。第一个选择包含SELECT,它对检索到的关联列进行排序,但第二个选择不排序,这似乎是从中填充集合的列。

注意,我已经尝试过配置NHibernate来进行外部联接提取,但没有标准就可以按预期工作。也就是说,它会在没有配置外部联接的情况下生成两个查询,但只有一个查询配置了外部联接。添加标准似乎无论如何都会引起额外的查询。

请使用条件API或解释为什么这不起作用限制答案。我知道可以通过映射完成排序,但我正在尝试使用条件方法了解具体问题。

====编辑====

以下是模型和映射:

order by

====编辑2 ====

作为更新,将Not.LazyLoad()添加到Parent后,只生成一个public class ParentEntity { public virtual int Id { get; private set; } public virtual IList<ChildEntity> Children { get; set; } public ParentEntity() { Children = new List<ChildEntity>(); } } public class ChildEntity { public virtual int Id { get; private set; } public virtual ParentEntity Parent { get; private set; } public virtual int Order { get; private set; } protected ChildEntity() { } public ChildEntity(int order) { Order = order; } } public class ParentEntityMap : ClassMap<ParentEntity> { public ParentEntityMap() { WithTable("Parent"); Id(p => p.Id); HasMany(p => p.Children) .KeyColumnNames.Add("Parent_Id") .Cascade.All(); } } public class ChildEntityMap : ClassMap<ChildEntity> { public ChildEntityMap() { WithTable("Child"); Id(c => c.Id); Map(c => c.Order, "[Order]"); References(c => c.Parent, "Parent_Id") .Cascade.All(); } } ,但结果仍未排序。

3 个答案:

答案 0 :(得分:1)

从我观察到的行为来看,问题似乎是虽然约束可以放在关联上(如docs的第12.4节所示),但这种约束只与它们充当根实体的有意义的过滤器。请考虑以下文档中的示例:

IList cats = sess.CreateCriteria(typeof(Cat))
.Add( Expression.Like("Name", "F%")
.CreateCriteria("Kittens")
    .Add( Expression.Like("Name", "F%") )
.List();

这就是说给我回到名字以“F”开头的所有猫,但只有那些猫的名字以“F”开头的猫。 这并不是说返回名称以“F”开头的小猫。订购以类似的方式工作。我们可能已经要求小猫按名称订购,NHibernate很乐意将其作为标准的一部分传递,但这样的排序与小猫的返回方式无关。因此,我的结论是使用Criteria API不能用于过滤或排序返回的关联。

文档的前面部分确实说明了返回的关联没有按标准进行预过滤,但在我理解了关联标准的用途之前,我并不完全明白其含义。

答案 1 :(得分:0)

你是如何映射孩子的? 如果您已将它们映射为“有序列表”(地图/列表/字典),则只能指示NHibernate应以有序方式检索子项。

例如: http://ayende.com/Blog/archive/2009/06/02/nhibernate-mapping-ltlistgt.aspx

我已将孩子们映射为无序列表(set / bag),然后NHibernate将无法为您排序孩子。在这种情况下,您必须在用户访问子项时对其进行排序

public class Parent
{
    private ISet<Child> _children = new HashedSet<Child>();

    public ReadOnlyCollection<Child> Children
    {
        new List<Child>(_children).OrderBy(child => child.SequenceNr).ToList().AsReadOnly();
    }

}

答案 2 :(得分:0)

有点难以看到你的模型和地图。但也许是这样的?

 var criteria = session.CreateCriteria<ParentEntity>();
 criteria.Add(Restrictions.Eq("Id", id))
                .CreateAlias("Children", "children")
                .AddOrder(Order.Desc("children.Order"));