Check for column name in a SqlDataReader object
public static class DataRecordExtensions
{
public static bool HasColumn(this IDataRecord dr, string columnName)
{
for (int i=0; i < dr.FieldCount; i++)
{
if (dr.GetName(i).Equals(columnName, StringComparison.InvariantCultureIgnoreCase))
return true;
}
return false;
}
}
Using Exception
s for control logic like in some other answers is considered bad practice and has performance costs. It also sends false positives to the profiler of # exceptions thrown and god help anyone setting their debugger to break on exceptions thrown.
GetSchemaTable() is also another suggestion in many answers. This would not be a preffered way of checking for a field's existance as it is not implemented in all versions (it's abstract and throws NotSupportedException in some versions of dotnetcore). GetSchemaTable is also overkill performance wise as it's a pretty heavy duty function if you check out the source.
Looping through the fields can have a small performance hit if you use it a lot and you may want to consider caching the results.
It's much better to use this boolean function:
r.GetSchemaTable().Columns.Contains(field)
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:
public static bool HasColumn(DbDataReader Reader, string ColumnName) {
foreach (DataRow row in Reader.GetSchemaTable().Rows) {
if (row["ColumnName"].ToString() == ColumnName)
return true;
} //Still here? Column not found.
return false;
}
In one line, use this after your DataReader retrieval:
var fieldNames = Enumerable.Range(0, dr.FieldCount).Select(i => dr.GetName(i)).ToArray();
Then,
if (fieldNames.Contains("myField"))
{
var myFieldValue = dr["myField"];
...
Edit
Much more efficient one-liner that does not requires to load the schema:
var exists = Enumerable.Range(0, dr.FieldCount).Any(i => string.Equals(dr.GetName(i), fieldName, StringComparison.OrdinalIgnoreCase));