I'm writing some helper functions that take a SqlDataReader and process the results. Now normally you'd structure the loop like so:
while(reader.read()){
// Read fields
}
But I my be passing the function a reader which is already positioned on a row, and in this case I want it to process the current row. The code above will only output the entire result set if read() had not been called prior to invoking the function.
I want the function to do something like this:
if(!reader._dataReady)
rowExists = reader.read() // Read
while(rowExists){
// read fields
rowExists = reader.read()
}
_dataReady is an actual member of SqlDataReader and seems to do what I need, however it's private! Surely there's a way to determine if the reader is positioned on an actual row, short of trying to read the field and catching the exception.
why not just subclass SqlDataReader, and create Read() method? I have it in all my projects, now:
public class SafeDataReader : IDataReader, SqlDataReader
{
public IDataReader reader {get;set;}
public int GetInt32(string aFieldName, int aDefault);
public int? GetInt32Nullable(string aFieldName);
....
}
You can use the FieldCount property. As per the documentation, it returns zero if not positioned in a valid recordset.
Some other solutions:
Do your Read() looping entirely outside of your helper method (and always operate only on the current row)
Do your Read() looping entirely within the helper method, and always pass it fresh data readers that have not been advanced
Do your first Read() outside of the data reader, continue Read() looping within the helper method, and always assume that the data reader has been advanced to the first record.
Probably overkill: write a wrapping implementation of IDataReader that forwards all calls to the underlying data reader (probably passed in via the constructor), but exposes a property indicating whether Read has ever been called.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With