如何在C#中检测DataReader上的EOF而不执行Read()

我熟悉使用.Read()来检测EOF

using (IDataReader reader = SqlHelper.ExecuteReader(_connectionString, "dbo.GetOrders")) { AssertOrder(reader); while (reader.Read()) { yield return FillRecord(reader, StringComparer.OrdinalIgnoreCase); } reader.Close(); } 

由于我遇到了一些奇怪的情况,FillRecord实际上推动了读者。 所以现在while循环中的.Read()实际上会导致这个函数跳过一些行 – 因为我们正在前进两次。

我希望有一个IDataReader.EOF,但没有。 有什么想法吗?

我想我可能会在评论中明确表达我的意见……但是,既然你要求“任何想法”……在这里你走了:

显然是一个两秒钟的黑客工作,但你会明白:

(你肯定想要实现IDisposable(因为我认为IDataReader是??)等等。可能只是让类inheritance自IDataReader,并将类实现为Facade。或者获得真正的酷并实现一个劫持Read的透明代理方法。

 public class DataReaderWithEOF { public bool EOF { public get; private set; } private IDataReader reader; public DataReaderWithEOF(IDataReader reader) { this.reader = reader; } public bool Read() { bool result = reader.Read(); this.EOF = !result; return result; } } 
 using (IDataReader reader = SqlHelper.ExecuteReader(_connectionString, "dbo.GetOrders")) { if(!reader.HasRows) { Response.Write("EOF"); // empty } while (reader.Read()) //read only registers { yield return FillRecord(reader, StringComparer.OrdinalIgnoreCase); } reader.Close(); } } 

你每次使用一个。 读()下一条记录。 然后做if(reader.Read())你已经推进了一个记录。

Steve的解决方案的另一种方法是在Read()返回false时调用FillRecord中的reader.Close()。 然后你可以检查reader.IsClosed在你的主循环中。