How do I check to see if a column exists in a SqlDataReader
object? In my data access layer, I have create a method that builds the same object for multiple stored procedures calls. One of the stored procedures has an additional column that is not used by the other stored procedures. I want to modified the method to accommodate for every scenario.
My application is written in C#.
It's much better to use this boolean function:One call - no exceptions. It might throw exceptions internally, but I don't think so.
NOTE: In the comments below, we figured this out... the correct code is actually this:
Here is a one liner linq version of the accepted answer:
How about
It probably would not be as efficient in a loop
My data access class needs to be backward compatible, so I might be trying to access a column in a release where it doesn't exist in the database yet. We have some rather large data sets being returned so I'm not a big fan of an extension method that has to iterate the DataReader column collection for each property.
I have a utility class that creates a private list of columns and then has a generic method that attempts to resolve a value based on a column name and output parameter type.
Then I can just call my code like so
Although there is no publicly exposed method, a method does exist in the internal class
System.Data.ProviderBase.FieldNameLookup
whichSqlDataReader
relies on.In order to access it and get native performance, you must use the ILGenerator to create a method at runtime. The following code will give you direct access to
int IndexOf(string fieldName)
in theSystem.Data.ProviderBase.FieldNameLookup
class as well as perform the book keeping thatSqlDataReader.GetOrdinal()
does so that there is no side effect. The generated code mirrors the existingSqlDataReader.GetOrdinal()
except that it callsFieldNameLookup.IndexOf()
instead ofFieldNameLookup.GetOrdinal()
. TheGetOrdinal()
method calls to theIndexOf()
function and throws an exception if-1
is returned, so we bypass that behavior.Columns.Contains
is case-insensitive btw.