Подтвердить что ты не робот

Получить отличительный результат из NHibernate с помощью API критериев?

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

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

4b9b3361

Ответ 1

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

session.CreateCriteria(typeof(Product)
    .Add(...)
    .SetResultTransformer(new DistinctEntityRootTransformer())

Ответ 2

Чтобы выполнить отдельный запрос, вы можете установить прогноз по критериям Projections.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.

Ответ 4

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

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

Итак, если вы пришли сюда, надеясь на способ сделать это, вы избегаете возиться с критериями, хотя вы, хотя вам все равно придется идти в этом направлении, просто добавив "DISTINCT" в ваш SQL... искать дальше

Ответ 5

Я также столкнулся с проблемой нечеткого количества элементов (я использую 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();