检查是否为sqldatareader中的最后一条记录

14

有没有办法检查我是否处于最后一条记录?谢谢


2
只是好奇,你为什么需要那个? - codingbiz
2
如果我在最后一条记录上,我想要进行一些异常处理!! - wben
6个回答

21

使用这个方法来识别和处理结果中的最后一行:

if (reader.Read())
{
    var loop = true;
    while (loop)
    {
        //1. Here retrive values you need e.g. var myvar = reader.GetBoolean(0);
        loop = reader.Read();
        if (!loop)
        {
            //You are on the last record. Use values read in 1.
            //Do some exceptions
        }
        else {
            //You are not on the last record.
            //Process values read in 1., e.g. myvar
        }
    }
}

4
我们只需要将 if(reader.Read()) 替换为 if(reader.HasRow)。 - wben
2
在这种情况下,您将无法在第一次迭代开始时读取值。 - Raman Zhylich
4
你的代码有误,当前的实现会跳过第一行记录。在 if (reader.Read()) 中,你将读取器设置到了第一行记录,然后又使用了 loop = reader.Read(),这将直接将读取器设置到第二条记录。不过,你的解决方案提供了如何解决问题的正确模式。 - Thorsten Dittmar
2
@ThorstenDittmar 如果你实际上阅读了代码注释,你就不会认为他跳过了第一条记录。他在if语句中前进到第一条记录,然后读取值,然后将loop = reader.Read()设置为第二条记录。 - user2966445
你说得没错,但是现在这个代码示例的格式非常误导人。 - Thorsten Dittmar

5
除了“后面没有其他的”之外,没有其他的了。这可能意味着您需要缓冲该行,尝试读取,然后查看缓冲的数据是否是最后一个。
在许多情况下,当数据适中且您正在构建某种对象模型时,您可以直接查看构造的数据,即使用阅读器创建所有行的List<T>,然后在此之后查看列表中的最后一行。

是的,但我不想传递两个循环嵌套!! - wben
@wben 如果它在列表中,循环是非常便宜的 - 或者只需通过索引器访问:list[list.Count-1]。当然,缓冲前一行甚至更便宜,但更复杂。 - Marc Gravell
@wben 为了让事情更清楚,接受的答案中,“//1. Here retrive values you need e.g. var myvar = reader.GetBoolean(0);”这句话就是我们所说的“缓冲行,尝试读取,然后查看缓冲数据是否为最后一行”。当然,代码示例可以使其更加清晰明了。 - Marc Gravell

1
遍历SqlDataReader的方法:
SqlDataReader reader = ...;
while(reader.Read())
{
    // the reader will contain the current row
}

读取器中没有任何内容告诉您这是最后一行。

如果您仍然需要进入最后一行,可以将该行数据存储在单独的变量中,在退出循环后获取该数据。

其他替代方案包括:

  • 将数据放入 DataSet/DataTable 中
  • 将数据存储在列表/数组中
  • 以相反的顺序检索数据(重写查询),使第一行成为您想要的行。

reader不是一个枚举器,它没有MoveNext()方法。你需要先请求枚举器,即reader.GetEnumerator()。 - Raman Zhylich
@RamanZhylich:你说得对。应该是reader.Read()。已修正!(编辑了帖子) - Arjan Einbu

1

另一种可能性是将信息放入数据集中。

您正在使用查询读取数据。我们称之为q。请改用此查询:

select row_number() over (order by (select NULL)) as seqnum,
       count(*) over (partition by null) as numrecs
       q.*,
from (<q>) q
order by seqnum

现在最后一条记录的序列号为numrecs,您可以在应用程序中进行测试。

顺便说一下,这假定您以无序方式检索数据。如果您想要排序,请将条件放入row_number()的“order by”子句中。


0

如果不重复自己(即两次获取记录),则无法这样做。以下是一种更短的方法

System.Data.DataTable dt = new System.Data.DataTable();
dt.Load(myDataReader);
int recordCount = dt.Rows.Count;
if(recordCount > 0)
{
   if(dt.Rows[recordCount-1]["username"] == "wrong value")
     throw new Exception("wrong value");
}

我随手写了这个,所以它没有经过测试,但这就是方法。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接