2

I Want to handle null values, for the column "ProductState" which returns a string. But isDBNull accepts only integer parameters. What needs to be changed here, please ?

string _productState = "";    

if (!dr.IsDBNull("ProductState"))
                    _productState= dr.GetString("ProductState");
                else
                    _productState= "";
4
  • IsDBNull required an index of the column not its name. Commented May 13, 2014 at 13:54
  • @Steve - MS-SQL only. Commented May 13, 2014 at 14:06
  • Then I suppose that also the GetString doesn't work because there is no GetString in the SqlClient namespace that takes a column name as parameter Commented May 13, 2014 at 14:09
  • That's could not be the case I suspect, as GetString is used smoothly for several other columns in the same fetch function Commented May 13, 2014 at 14:19

5 Answers 5

4

SqlDataReader.GetOrdinal is your answer

if (!dr.IsDBNull(dr.GetOrdinal("ProductState")))

You could write an extension method to encapsulate this functionality

public static class ReaderExtensions
{
     public static bool IsDBNull(this SqlDataReader reader, string colName)
     {
          return reader.IsDBNull(reader.GetOrdinal(colName));
     }
}

And now you will be able to call the IsDBNull passing a string

if (!dr.IsDBNull("ProductState"))

Looking at your code (reader.GetString("ProductState")) I thought that you are using the MySql provider that supplies an extension GetString (and other GetXXXX) that takes a column name as parameter. But if you have an SqlDataReader then you need to change also that call using the GetOrdinal (or another extensions) because the SqlClient doesn't have a GetString with a column name as parameter

Sign up to request clarification or add additional context in comments.

4 Comments

Your extension method is not right. Shouldn't it be reader.IsDBNull(reader.GetOrdinal(colName)); with a bool result instead of int? Also you could use IDataReader and the extension method would work with SqlDataReader and MySqlDataReader.
I'm getting this error: DataPortal.Fetch failed (System.IndexOutOfRangeException: ProductState).
IndexOutOfRange is documented to return if The name specified is not a valid column name.
May be my actual issue related with the column name instead, I need to figure that out. but thanks Gentlemen for this much help and explanation.
2

Try this:

if (!dr.IsDBNull(dr.GetOrdinal("ProductState")))

Comments

1

You can compare it with DBNull.Value like

if(dr["ProductState"] != DBNull.Value)

Comments

1

I use this quick tip:

Casting using as returns null if the field contains DBNull.Value.

if (dr["ProductState"] as string == null)
{
    ...
}

Also, I can use the ?? operator to obtain a fallback value directly in one line if the field contains DBNull.Value

var productState = dr["ProductState"] as string ?? "";

Comments

0

We have a collection of extension methods that can either handle this generically for all column types, or extensions for specific types, which makes the code read like the original set of DataReader methods. So for string, we have these two extensions, which allow for both column ordinal or name, whichever you have access to:

/// <summary>Checks for null before calling GetString.</summary>
/// <returns>The string value of the column, or null if the column is <see cref="DBNull"/>.</returns>
public static string GetNullableString(this IDataRecord row, int i)
{
  object val;
  if((val = row.GetValue(i)) == DBNull.Value)
    return null;
  return val.ToString();
}

/// <summary>Checks for null before calling GetString.</summary>
/// <returns>The string value of the column, or null if the column is <see cref="DBNull"/>.</returns>
public static string GetNullableString(this IDataRecord row, string name)
{
  object val;
  if((val = row[name]) == DBNull.Value)
    return null;
  return val.ToString();
}

and you could modify this to accept a replacement value for null, although we have extension methods that are string specific for that rather than at the DataReader level...again, just to separate concerns:

/// <summary>Checks for null before calling GetString.</summary>
/// <returns>The string value of the column, or <paramref name="defaultVal'/> if the column is <see cref="DBNull"/>.</returns>
public static string GetNullableString(this IDataRecord row, string name, string defaultVal)
{
  object val;
  if((val = row[name]) == DBNull.Value)
    return defaultVal;
  return val.ToString();
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.