NHibernate Criteria QueryByExample застрял с SQL посередине

Я использую Criteria для ускорения запроса, и я почти достиг цели.

Использование Query By Example для сопоставления строк в таблице, удаления повторяющихся строк с одинаковым идентификатором, а затем разбиения на страницы.

Конечно, я не могу разбить на страницы, пока не удалю повторяющиеся строки, и я не знаю, как это сделать. Это можно сделать в SQL, но тогда это соответствует свободному коду, ISQLQuery не возвращает объект ICriteria.

    public IList<EntitySearch> CriteriaSearch(EntitySearch exampleEntitySearch, int startingPage, int pageSize)
    {
        var startRow = startingPage * pageSize;

        // Query By Example.
        var example = Example.Create(exampleEntitySearch)
            .IgnoreCase()
            .EnableLike(MatchMode.Anywhere)
            .ExcludeZeroes();

        var results = this.Session.CreateCriteria(typeof(EntitySearch))
                                .Add(example)
        // select * from (SELECT ROW_NUMBER()OVER (partition by Id order by Id) As rankOrder, * FROM EntitySearch) as original where original.rankOrder = 1
                                .SetFirstResult(startRow)
                                .SetMaxResults(pageSize)
                                .List<DealSearch>();

        return results;
    }

Совет, который я прочитал, состоит в том, чтобы написать SQL-запрос в NHibernate, но я не могу придумать, как преобразовать отличный «ROW_NUMBER() по разделу SQL». Я хотел бы сначала заставить его работать от начала до конца, а затем сделать его более элегантным.

Я хотел бы запустить этот всплеск в производство и доказать ускорение ~ 90%.


person zeristor    schedule 04.11.2011    source источник
comment
Ну, вы можете заставить NHibernate выполнять жестко закодированный SQL в вашем коде, но тогда вы потеряете кучу преимуществ, которые NHibernate дает вам, таких как безопасность типов (строгая типизация из карты классов в объекты БД), независимость от механизма БД (больше сложный SQL не будет работать на всех БД), ленивая загрузка, кэширование и т. д. Я бы рекомендовал, если только это не является абсолютно необходимым и вы уверены, что никогда не будете переключать механизмы БД, не используйте жестко закодированный SQL в коде с NHibernate.   -  person Jesse Webb    schedule 04.11.2011
comment
Боюсь, жестко закодированный SQL лучше, чем ничего. Изучив еще немного, критерии не обязательно должны быть в правильном порядке, и я должен иметь возможность использовать ExpressionSQL. Мой запрос сводился к определенному биту SQL, который использует ROW_NUMBER по разделу, чтобы взять первый элемент в каждой подгруппе. Что необходимо перед разбиением на страницы.   -  person zeristor    schedule 07.11.2011
comment
На этом форуме вам может помочь опытная команда: sqlserver.ro, попробуйте там   -  person radu florescu    schedule 24.12.2011


Ответы (1)


Я не уверен в производительности, но вы можете использовать LINQ:

Изменять:

.List<DealSearch>();

To:

.List<DealSearch>().Distinct().ToList();
person BaTTy.Koda    schedule 05.01.2012
comment
Идея использования Criteria состоит в том, чтобы выполнять обработку на сервере и, таким образом, уменьшать объем данных, передаваемых на сервер. LINQ для NHibernate будет работать только после доставки данных. Однако на SQL Server есть .NET, о чем я не подумал. - person zeristor; 06.01.2012
comment
Понял, я пропустил часть о том, чтобы сделать это на стороне сервера (что имеет смысл), я просто смотрел на получение отдельного набора результатов. У меня нет времени смотреть прямо сейчас, но смотрели ли вы на SetResultTransformer с помощью DistinctEntityRootTransformer? - person BaTTy.Koda; 06.01.2012