ADO.Net: check if field name exists in IDataRecord

Is there a better way to get the field_name value from IDataRecord only if the file_name exists in IDataRecord, I am currently using try {...} catch {...} block, but this is some On Error Resume next function. Some alternatives?

/// <summary> /// Returns column value from IDataRecord only if field_name exists. /// </summary> public static Tresult ValueIfExists<Tresult>(this IDataRecord record, string field_name) { try { return record.Value<Tresult>(record.GetOrdinal(field_name)); } catch { return default(Tresult); } } /// <summary> /// Returns column value from IDataRecord accecing by index. /// </summary> public static Tresult Value<Tresult>(this IDataRecord record, int field_index) { return record.IsDBNull(field_index) ? default(Tresult) : (Tresult)Convert.ChangeType(record[field_index], typeof(Tresult)); } 

I modified my ValueIfExists function to reflect your ideas, so it looks like this:

 public static Tresult ValueIfExists2<Tresult>(this IDataRecord record, string field_name) { for (int index = 0; index < record.FieldCount; index++) { if (record.GetName(index).Equals(field_name, StringComparison.InvariantCulture)) { return record.Value<Tresult>(record.GetOrdinal(field_name)); } } return default(Tresult); } 
+7
source share
4 answers

You are correct that exceptions should not be used for normal program flow.

The GetOrdinal method GetOrdinal designed for situations where you know which fields you are receiving, and if there is no field, this is an error that should lead to an exception.

If you do not know which fields you will get as a result, you should avoid the GetOrdinal method. Instead, you can get all the names and their index into a dictionary, which you can use as a replacement for the GetOrdinal method:

 public static Dictionary<string, int> GetAllNames(this IDataRecord record) { var result = new Dictionary<string, int>(); for (int i = 0; i < record.FieldCount; i++) { result.Add(record.GetName(i), i); } return result; } 

You can use the ContainsKey method to check if a name exists in the dictionary, or the TryGetValue method to check if this name exists and index it in one operation.

The GetOrdinal method first searches for a sensitive case, and if that fails, it searches the case without checking. This is not provided by the dictionary, so if you want this exact behavior, you prefer to store the names in an array and write a method to scroll through them when you want to find the index.

+16
source share

Take a look at this closely related question for a viable testing approach for field existence. Note: if you are iterating over a result set, it is probably best to check one column, rather than at each iteration.

Check column name in SqlDataReader object

+2
source share

With one line:

 bool exists = Enumerable.Range(0, dataRecord.FieldCount).Any(x => dataRecord.GetName(x) == "columnName"); // or with OrdinalIgnoreCase 
+2
source share

I always use the following approach for IDataReader (since most IDataRecord you get readers) reader.GetSchemaTable().Columns.Contains("field")

Of course, if you have a genuine IDataRecord , then this will not succeed if you try to apply it to IDataReader , and this is not one.

+1
source share

All Articles