我有这个需要重构的旧项目。 我开始使用最新版本的Nhibernate重写一些查询。 我有这个查询,需要返回一个带有顺序的分页的不同Id列表。 问题是,您似乎无法通过未包含在select语句中的属性执行订单。但是我不想选择其他列,我只想要id。
有没有办法确保我只获取ID并仍然获得分页不同的列表?
这是我现在所拥有的简化版本:
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:不是SELECTed表达式。
有人知道如何使用子查询或其他东西来解决这个问题吗?
我不习惯Nhibernate所以我真的不知道。
答案 0 :(得分:0)
在标准SQL本身中,您不能对select子句中不存在的列进行排序(按顺序排列)。
请告诉我为什么当您需要StudentId时,您需要在DatumInplanning上进行排序?如果需要,您还可以选择使用原始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无法做到这一点。如果按顺序排列,则必须在select distinct 子句中包含列名。以下是您的替代方案。
1)在结果中获取两列,并在应用程序中进行操作以获得所需的确切数据。
2)更改为自定义SQL,如下(子SQL)。我在Oracle中测试了这个。它运作良好。
select ID from (select ID from student order by Birthday);
但是,如果按顺序对子列进行明确的排序,则有业务结果问题。请参见下图。 ID 2属于生日4,6,8。因此,当您按生日进行订购,并获得ID时,不同的结果将不一致。给我你的表结构和你想要获取的结果。如果我可以从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)不要使用distinct子句,你应该能够按生日过滤它。