【问题标题】:Nhibernate Distinct with Order By (Oracle DB)Nhibernate Distinct with Order By (Oracle DB)
【发布时间】:2015-09-03 08:06:25
【问题描述】:

我有一个需要重构的旧项目。 我开始使用最新版本的 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: not a SELECTed expression。 有人知道如何使用子查询或其他东西来解决这个问题吗? 我不习惯 Nhibernate,所以我真的不知道。

【问题讨论】:

    标签: c# oracle nhibernate queryover


    【解决方案1】:

    在标准 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);
    

    但是,当您对 order by 子句中不存在的列进行不同的排序时,会出现业务结果问题。请看下图。 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 子句,您应该能够按生日过滤它。

    【讨论】:

    • 对不起荷兰人,我现在把 DatumInplanning 改成了 BirthDay。由于分页,我需要 order by。这些 id 用于另一个选择,但我每次只选择 50,它们需要按照我想在屏幕上显示它们的确切顺序。
    • 我已经通过编辑我之前的回答来回答。请查看并告诉我这是否可以解决您的问题
    • 我知道这行得通,但我们也需要一个独特的。因为连接了很多表(进行一些过滤),所以结果中有重复项。但是一旦你有了一个不同的,它就会失败,除非你使用子查询,但我似乎无法弄清楚如何让它在 Nhibernate 中工作。
    • 答案在上面编辑。用 1 个插图说明如果您为未选择的列设置不同的排序也可能给出错误的业务结果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-10
    • 1970-01-01
    相关资源
    最近更新 更多