如何访问数据读取器中的特定行?
How to access specific row in datareader?
我在下载批量报告时收到 OutOfMemoryException
。因此,我使用 DataReader
而不是 DataSet
来更改代码。
如何在 DataReader
中实现以下代码,因为我无法在我的编码中使用任何 DataTables
和 DataSet
。
if (dataSet.Tables[0].Rows[i + 1]["Sr No"].ToString() == dataSet.Tables[0].Rows[i]["Sr No"].ToString())
我认为您不能访问尚未执行的行。按照我的理解,DataReader return 逐行从数据库中读取数据。
您可以尝试以下方法:
这将遍历 DataReader 将 return 数据集中的每一行。这里可以查看某些values/conditions,如下:
while (dataReader.Read())
{
var value = dataReader["Sr No"].ToString();
//Your custom code here
}
或者,如果您愿意,也可以指定列索引而不是名称,如下所示:
while (dataReader.Read())
{
var value = dataReader.GetString(0); //The 0 stands for "the 0'th column", so the first column of the result.
//Your custom code here
}
更新
为什么不将从 DataReader
中读取的所有值放入一个列表中,如果需要,以后可以使用此列表进行值之间的比较。
不要在客户端过滤行。
最好在服务器上搜索正确的行,甚至在它们到达客户端之前,而不是将所有行提取到客户端然后在那里过滤。只需将您的搜索条件合并到 SQL 查询本身,然后获取服务器已经为您找到的行。
这样做:
- 允许服务器使用索引和其他数据库结构来识别 "interesting" 行可能比线性搜索所有行快得多。
- 客户端和服务器之间的网络连接不会被大量的行所饱和,其中大部分最终都会被丢弃。
- 可能允许您的客户端以一种简单的方式一次处理一行(例如使用
DbDataReader
),而不是额外处理 and/or 在内存中存储多行(甚至全部)行,就像你一样)。
在您的特定情况下,您似乎需要一个自连接函数,或者可能需要一个分析函数(又名 "window")。在不了解您的数据库结构或您实际想要完成什么的情况下,我无法知道您的确切查询将是什么样子,可能是这样的:
-- Sample data...
CREATE TABLE T (
ID int PRIMARY KEY,
SR_NO int
);
INSERT INTO T VALUES
(1, 100),
(2, 101),
(3, 101),
(4, 100);
-- The actual query...
SELECT
*
FROM (
SELECT
*,
LEAD(SR_NO) OVER (ORDER BY ID) NEXT_SR_NO
FROM
T T1
) Q
WHERE
SR_NO = NEXT_SR_NO;
结果:
ID SR_NO NEXT_SR_NO
2 101 101
您可以使用 do-while 循环来完成此操作。在检查条件之前,将读取下一行,您也可以访问该行。试试这个代码:
do
{
your code
}
while(myreader.Read())
我在下载批量报告时收到 OutOfMemoryException
。因此,我使用 DataReader
而不是 DataSet
来更改代码。
如何在 DataReader
中实现以下代码,因为我无法在我的编码中使用任何 DataTables
和 DataSet
。
if (dataSet.Tables[0].Rows[i + 1]["Sr No"].ToString() == dataSet.Tables[0].Rows[i]["Sr No"].ToString())
我认为您不能访问尚未执行的行。按照我的理解,DataReader return 逐行从数据库中读取数据。
您可以尝试以下方法:
这将遍历 DataReader 将 return 数据集中的每一行。这里可以查看某些values/conditions,如下:
while (dataReader.Read())
{
var value = dataReader["Sr No"].ToString();
//Your custom code here
}
或者,如果您愿意,也可以指定列索引而不是名称,如下所示:
while (dataReader.Read())
{
var value = dataReader.GetString(0); //The 0 stands for "the 0'th column", so the first column of the result.
//Your custom code here
}
更新
为什么不将从 DataReader
中读取的所有值放入一个列表中,如果需要,以后可以使用此列表进行值之间的比较。
不要在客户端过滤行。
最好在服务器上搜索正确的行,甚至在它们到达客户端之前,而不是将所有行提取到客户端然后在那里过滤。只需将您的搜索条件合并到 SQL 查询本身,然后获取服务器已经为您找到的行。
这样做:
- 允许服务器使用索引和其他数据库结构来识别 "interesting" 行可能比线性搜索所有行快得多。
- 客户端和服务器之间的网络连接不会被大量的行所饱和,其中大部分最终都会被丢弃。
- 可能允许您的客户端以一种简单的方式一次处理一行(例如使用
DbDataReader
),而不是额外处理 and/or 在内存中存储多行(甚至全部)行,就像你一样)。
在您的特定情况下,您似乎需要一个自连接函数,或者可能需要一个分析函数(又名 "window")。在不了解您的数据库结构或您实际想要完成什么的情况下,我无法知道您的确切查询将是什么样子,可能是这样的:
-- Sample data...
CREATE TABLE T (
ID int PRIMARY KEY,
SR_NO int
);
INSERT INTO T VALUES
(1, 100),
(2, 101),
(3, 101),
(4, 100);
-- The actual query...
SELECT
*
FROM (
SELECT
*,
LEAD(SR_NO) OVER (ORDER BY ID) NEXT_SR_NO
FROM
T T1
) Q
WHERE
SR_NO = NEXT_SR_NO;
结果:
ID SR_NO NEXT_SR_NO
2 101 101
您可以使用 do-while 循环来完成此操作。在检查条件之前,将读取下一行,您也可以访问该行。试试这个代码:
do
{
your code
}
while(myreader.Read())