2015-09-03 3 views
0

У меня есть этот старый проект, который нуждается в рефакторинге. Я начал переписывать некоторые запросы, используя новейшую версию Nhibernate. У меня есть этот запрос, который должен вернуть выписанный отдельный список идентификаторов с порядком. Проблема в том, что вы не можете сделать заказ по свойствам, которые не включены в оператор select. Но я не хочу выбирать другие столбцы, мне нужен только идентификатор.Nhibernate Distinct with Order By (Oracle DB)

Есть ли способ убедиться, что я только получаю идентификаторы и все еще получаю выбитый по перечню отдельный список?

Это упрощенная версия того, что я сейчас:

Student student = null; 
Locker locker = null; 
Teacher teacher = null; 
Grade grade = null; 

var baseQuery = SessionHandler.CurrentSession.QueryOver(() => student) 
    .JoinAlias(() => cat.Locker,() => locker) 
    .JoinAlias(() => cat.Teachers,() => teacher) 
    .JoinAlias(() => cat.Grades,() => grade)); 

if (gender.HasValue) 
{ 
    baseQuery.Where(() => student.Gender == gender.Value); 
} 

if (hallway.HasValue) 
{ 
    baseQuery.Where(() => locker.Hallway == hallway.Value); 
} 

... 

baseQuery.Select(Projections.Distinct(Projections.Property(() =>  student.StudentId))); 
baseQuery.OrderBy(b => student.Birthday, OrderSettings.Direction); 
var results = baseQuery.Skip(50).Take(50).List<TKey>(); 

код, как это всегда бросает ORA-01791: не выбранного выражения. Кто-нибудь знает, как исправить это, используя подзапрос или что-то еще? Я не привык к Nhibernate, поэтому я действительно понятия не имел.

ответ

0

В стандартном SQL вы не можете сортировать (помещать в порядке порядка) в столбец, которого нет в предложении select.

Пожалуйста, дайте мне знать, почему вам нужна сортировка по DatumInplanning, когда вам просто нужен StudentId? При необходимости вы также можете использовать синтаксис необработанного SQL.

var query = "SELECT TOP 10000 o.* " 
      + " from ORDERS o where o.Year in (:orderYear));"; 

var session = sessionFactory.OpenSession(); 
var result =session.CreateSQLQuery(query) 
       .AddEntity(typeof(Order)) 
       .SetInt32("orderYear",2012) 
       .List<Order>(); 

В SQL это невозможно. Вы можете это сделать. У вас должно быть имя столбца в элементе , отличное от, если вы заказываете заказ. Вот альтернативы для вас.

1) Получите обе колонки в результатах и ​​сделайте манипуляции в своем приложении, чтобы получить точные данные, которые вы хотите.

2) Перейдите на пользовательский SQL, как показано ниже (под SQL). Я тестировал это в Oracle. Он работал хорошо.

select ID from (select ID from student order by Birthday); 

Однако проблема с бизнес-результатом возникает, когда вы выполняете разбор сортировки по столбцу, который не существует в порядке по условию. См. Рисунок ниже. ID 2 относится к датам рождения 4,6,8. Поэтому, когда вы делаете заказ по дате рождения и получаете идентификатор, отдельные результаты не будут согласованы. Дайте мне вашу структуру таблицы и результаты, которые вы хотите получить. Позвольте мне дать шанс, если я могу исправить это со стороны SQL.

SQL> select id,birthdate from student order by birthdate; 

     ID BIRTHDATE 
---------- --------- 
     0 29-AUG-15 
     5 29-AUG-15 
     1 03-SEP-15 
     2 04-SEP-15 
     3 06-SEP-15 
     2 06-SEP-15 
     2 08-SEP-15 

7 rows selected. 

SQL> select distinct id from (select id,birthdate from student order by birthdat 
e); 

     ID 
---------- 
     1 
     2 
     5 
     3 
     0 

3) Не помещайте отдельное положение, и вы должны иметь возможность фильтровать его по дням рождения.

+0

Извините за голландское право, я изменил DatumInplanning на BirthDay сейчас. Мне нужен заказ из-за пейджинга. Эти идентификаторы используются для другого выбора, но я выбираю только 50 каждый раз, и они должны быть в точном порядке, так как я хочу отображать их на экране. – Beejee

+0

Я ответил, отредактировав свой ранее ответ. Пожалуйста, просмотрите и дайте мне знать, если это решит вашу проблему. –

+0

Я знаю, что это работает, но нам также нужен отчет. Поскольку множество таблиц соединено (чтобы сделать некоторую фильтрацию), в результатах есть дубликаты. Но как только вы дате отчет, он потерпит неудачу, если вы не используете подзапросы, но я не могу понять, как заставить это работать в Nhibernate. – Beejee