【问题标题】:OracleDataReader returning only last row on pagination queryOracleDataReader 仅返回分页查询的最后一行
【发布时间】:2017-05-12 20:28:40
【问题描述】:

我正在使用 Oracle.ManagedDataAccess 从我的数据库中返回数据,我确实需要对结果进行分页,因为该表中有很多寄存器。

所以我使用this 发布的第二个答案来分页,当我在 Oracle 客户端上运行时它确实有效。

最终查询如下所示:

select *
from (
    select rownum as rn, a.*
    from (
            Select  u.*
            From users u
            order by u.user_code
         ) a
     )
where   rownum <= :myReturnSize
and     rn > (:myReturnPage-1) * :myReturnSize;

但是当我从下面的 .Net 代码中调用它时,它只返回我要求的 100 的最后一个寄存器。

OracleParameter[] parameters = new OracleParameter[]{
    new OracleParameter("myReturnPage", page), //1
    new OracleParameter("myReturnSize", size)  //100
};

List<User> usersList = new List<User>();

using (OracleConnection conn = new OracleConnection(connString))
{
    using (OracleCommand cmd = new OracleCommand(sbSelect.ToString(), conn))
    {
        conn.Open();
        cmd.CommandType = CommandType.Text;
        cmd.Parameters.AddRange(parameters);

        using (OracleDataReader odr = cmd.ExecuteReader())
        {
            if (!odr.IsClosed && odr.HasRows)
            {
                while (odr.Read())
                {
                    User userToReturn = new User();
                    FillUserEntity(userToReturn, odr);
                    usersList.Add(userToReturn);
                }
            }
        }
    }
}

return usersList.AsQueryable();

更奇怪的是,当我在同一方法中不分页运行此查询时,它会返回所有寄存器,超过 723,000 个。

任何帮助将不胜感激。

非常感谢。

【问题讨论】:

    标签: c# oracle pagination


    【解决方案1】:

    默认情况下,ODP.Net 按位置而不是名称设置参数。所以你只需要在创建 OracleParameter 的数组时颠倒顺序,并将 BindByName 属性设置为 true,如下所示:

    cmd.BindByName = true;
    

    【讨论】:

      【解决方案2】:

      您能否确认您的查询是否从 Oracle 客户端提供了正确的输出?

      问题在于 其中 rownum

      一种可能的解决方案是

      选择 * 从 ( 选择 rownum 作为 rnum, a.* 从 ( 选择 rownum 作为 rn, u.* 来自用户 由 u.user_code 订购 ) 一种 ) 其中 rnum (:myReturnPage-1) * :myReturn.

      【讨论】:

      • 我的答案格式不正确,可能是因为我是从移动应用发布的。
      • 感谢您的回复。从这个原则开始,我发现出于某种疯狂的原因,Oracle.ManagedDataAccess.Client 正在更改参数。我想,因为当我问的时候,.Net 只返回了最后一个寄存器,而你的回答返回了第一个。所以我改变了价值观,它奏效了。
      【解决方案3】:

      Oracle 倾向于使用存储过程而不是直接文本(出于某种原因)。我有很多“它在 SQL Developer 中有效,但在 .Net 中无效!”通过将它们全部放在数据库端包内的存储过程中来解决的情况。这也将您的查询与您的应用程序分离,因此如果查询必须更改,您不必重新编译应用程序。然后,您的应用程序只进行与以前相同的调用,但可能使用 OracleDataAdapter 对存储过程进行调用。

      【讨论】:

      • 感谢您的快速回复,但这不是我的情况,与程序创建有关。如果我需要更改查询,我将通过发布过程,如果我需要重新编译 proc 或应用程序,这没有什么区别。
      • 此外,我在文本中使用参数的其他方法工作起来很神奇,所以我认为这不是我的问题。不过还是感谢您的宝贵时间。
      猜你喜欢
      • 2013-07-04
      • 2018-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-01
      • 2022-01-01
      相关资源
      最近更新 更多