在 NHibernate 中选择引用实体而不是根实体,按使用次数排序
Selecting referenced entity instead of root entity in NHibernate, ordered by usage count
我有以下两个对象模型:
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'.
类型的列表
从 NHibernate 5.1+ 开始,您可以使用 Entity projection
到 select 个引用的实体。但是实体投影不支持分组(大多数情况下分组可以用子查询代替):
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();
我有以下两个对象模型:
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'.
类型的列表从 NHibernate 5.1+ 开始,您可以使用 Entity projection 到 select 个引用的实体。但是实体投影不支持分组(大多数情况下分组可以用子查询代替):
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();