在NHibernate中选择引用实体而不是根实体,按使用次数排序

时间:2018-08-29 12:03:06

标签: nhibernate queryover nhibernate-projections

我有以下两个对象模型:

public class Product
{
    public int IdProduct;
    public Category IdCategory;
    public string Name;
    public bool Available;
}

public class Category
{
    public int IdCategory;
    public string Name;
}

我想要一个所有类别的列表,以最常用的类别排在列表顶部。 我提出了以下NHibernate查询:

Product productAlias = null;
Category categoryAlias = null;
Category categoryAliasOutput = null;

session.QueryOver<Product>(() => productAlias)
    .JoinAlias(p => p.Category, () => categoryAlias, JoinType.RightOuterJoin)
    .Select(Projections.ProjectionList()
        .Add(Projections.Group(() => categoryAlias.IdCategory).WithAlias(() => categoryAliasOutput.IdCategory))
        .Add(Projections.Group(() => categoryAlias.Name).WithAlias(() => categoryAliasOutput.Name))
        .Add(Projections.Count(() => productAlias.IdCategory.IdCategory)))
    .OrderBy(Projections.Count(() => productAlias.IdCategory.IdCategory)).Desc
    .ThenBy(Projections.Property(() => categoryAlias.Name)).Asc
    .TransformUsing(Transformers.AliasToBean<Category>())
    .List<Category>();

这可行,但是我正在寻找一种简化代码的方法,因为它看起来很丑陋。 这也是一个简化的示例。就我而言,我正在处理具有更多属性的对象,所有这些属性都必须添加到ProjectionList中。

我不能使用“ Transformers.RootEntity”,因为根实体的类型为“ Product”,并且结果必须为“ Category”类型的列表。

1 个答案:

答案 0 :(得分:2)

自NHibernate 5.1+起,您可以使用Entity projection 选择引用的实体。但是实体投影不支持分组(在大多数情况下,可以用子查询代替分组):

Product productAlias = null;
Category categoryAlias = null;

session.QueryOver<Product>(() => productAlias)
    .JoinAlias(p => p.IdCategory, () => categoryAlias, JoinType.RightOuterJoin)
    .Select(p => categoryAlias.AsEntity())
    .OrderBy(
        Projections.SubQuery(
            QueryOver.Of<Product>()
            .Where(p => p.IdCategory == categoryAlias)
            .Select(Projections.RowCount()))).Desc
    .ThenBy(Projections.Property(() => categoryAlias.Name)).Asc
    .List<Category>();

在您的情况下,似乎也不需要引用实体,并且查询可以简化为:

Category categoryAlias = null;
var catergories = session.QueryOver(() => categoryAlias)
    .OrderBy(
        Projections.SubQuery(
            QueryOver.Of<Product>()
            .Where(p => p.IdCategory == categoryAlias)
            .Select(Projections.RowCount())))
    .Desc
    .List();