Получить отчетливый набор результатов из NHibernate, используя Criteria API? - PullRequest
29 голосов
/ 25 ноября 2008

Я пытаюсь получить отличные результаты, используя Criteria API в NHibernate. Я знаю, что это возможно с помощью HQL, но я бы предпочел сделать это с помощью API Criteria, потому что остальная часть моего приложения написана с использованием только этого метода. Я нашел это сообщение на форуме , но не смог заставить его работать. Есть ли способ с помощью API критериев получить различные наборы результатов?

Редактировать: При этом я также хотел исключить столбец Первичный ключ, который также является идентификатором, и получить оставшиеся отдельные записи. Есть ли способ сделать это? Таким образом, отдельные записи возвращают дубликаты, поскольку первичный ключ уникален для каждой строки, но все остальные поля одинаковы.

Ответы [ 5 ]

88 голосов
/ 22 декабря 2008

Для выполнения отдельного запроса вы можете установить прогноз по критериям в Projection.Distinct. Затем вы включаете столбцы, которые вы хотите вернуть. Затем результат превращается обратно в объект со строгой типизацией, устанавливая преобразователь результата в AliasToBeanResultTransformer - передавая тип, в который должен быть преобразован результат. В этом примере я использую тот же тип, что и сам объект, но вы можете создать другой класс специально для этого запроса.

ICriteria criteria = session.CreateCriteria(typeof(Person));
criteria.SetProjection(
    Projections.Distinct(Projections.ProjectionList()
        .Add(Projections.Alias(Projections.Property("FirstName"), "FirstName"))
        .Add(Projections.Alias(Projections.Property("LastName"), "LastName"))));

criteria.SetResultTransformer(
    new NHibernate.Transform.AliasToBeanResultTransformer(typeof(Person)));

IList<Person> people = criteria.List<Person>();

Это создает SQL, похожий на (по крайней мере, на SQL Server):

SELECT DISTINCT FirstName, LastName from Person

Обратите внимание, что в результате будут заполнены только те свойства, которые вы указали в своей проекции.

Преимущество этого метода заключается в том, что фильтрация выполняется в базе данных, а не возвращает все результаты вашему приложению, а затем выполняет фильтрацию, что является поведением DistinctRootEntityTransformer.

24 голосов
/ 25 ноября 2008

Не удается просмотреть сообщение на форуме (неработающая ссылка?), Поэтому, возможно, это не ответ, но вы можете добавить DistinctRootEntityResultTransformer:

session.CreateCriteria(typeof(Product)
    .Add(...)
    .SetResultTransformer(new DistinctEntityRootTransformer())
6 голосов
/ 27 апреля 2009

Для чего это стоит, NHibernate: Оптимизация запросов с помощью проекций помог мне в основном с этой же проблемой.

0 голосов
/ 12 ноября 2014

Мы используем самые современные и мощные и впечатляюще крошечные средства из всех, чтобы справиться с этим ... читайте дальше, только если вы готовы к удивительным ... и это НИЧЕГО не имеет отношения к критериям ...

CurrentSession()
    .QueryOver<GoodBadAndUgly>
    .Where(...)
    .TransformUsing(Transformers.DistinctRootEntity)

Итак, если вы пришли сюда в надежде найти способ сделать это, в котором вы избежите путаницы с Критериями, даже если вам все же придется пойти в этом направлении, просто чтобы добавить DISTINCT в ваш SQL ... не искать дальше

0 голосов
/ 07 июля 2009

Я также столкнулся с проблемой нечетного количества элементов (я использую fetch = "join" в моем файле отображения). Я использовал Linq To Nhibernate для решения проблемы, которая используется следующим образом:

       var suppliers = (from supplier in session.Linq<Supplier>()
                        from product in supplier.Products
                        where product.Category.Name == produtCategoryName
                        select supplier).ToList().Distinct();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...