Выбор ссылочной сущности вместо корневой сущности в NHibernate, упорядоченный по количеству использования - PullRequest
0 голосов
/ 29 августа 2018

У меня есть две следующие объектные модели:

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 голосов
/ 30 августа 2018

Начиная с NHibernate 5.1+ вы можете использовать Проекция объекта выбрать ссылочные объекты. Но группировка не поддерживается для проекций объектов (в большинстве случаев группировку можно заменить подзапросом):

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