我使用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。
任何帮助都将不胜感激。
非常感谢。
答案 0 :(得分:3)
默认情况下,ODP.Net按位置设置参数,而不是按名称设置。所以你只需要在创建OracleParameter数组时反转顺序,并将BindByName属性设置为true,如下所示:
cmd.BindByName = true;
答案 1 :(得分:1)
Oracle倾向于选择存储过程而不是直接文本(因为原因)。我有不止一些“它在SQL Developer中工作,但不是.Net!”通过将所有内容放在数据库端的包中的存储过程中解决的情况。这也将您的查询与应用程序分离,因此如果查询必须更改,则不必重新编译应用程序。然后,您的应用程序只是进行与之前相同的调用,但是对于存储过程,可能使用OracleDataAdapter。
答案 2 :(得分:1)
您能否确认是否查询从Oracle客户端提供正确的输出。?
问题在于 其中rownum&lt; =:myReturnSize 它将始终返回值rownum =:myReturnSize
一种可能的解决方案是
选择* 来自( 选择rownum作为rnum,a。* 来自( 选择rownum为rn,u。* 来自用户你 按u.user_code排序 ) 一个 ) 其中rnum&lt; =:myReturnSize 并且&gt; (:myReturnPage-1)*:myReturn。