我使用SQLdatareader从数据库构建poco。除非在数据库中遇到空值,否则代码可以正常工作。例如,如果数据库中的FirstName列包含空值,则抛出异常。

employee.FirstName = sqlreader.GetString(indexFirstName);

在这种情况下处理空值的最佳方法是什么?


当前回答

private static void Render(IList<ListData> list, IDataReader reader)
        {
            while (reader.Read())
            {

                listData.DownUrl = (reader.GetSchemaTable().Columns["DownUrl"] != null) ? Convert.ToString(reader["DownUrl"]) : null;
                //没有这一列时,让其等于null
                list.Add(listData);
            }
            reader.Close();
        }

其他回答

这个方法依赖于indexFirstName,它应该是一个从零开始的列序数。

if(!sqlReader.IsDBNull(indexFirstName))
{
  employee.FirstName = sqlreader.GetString(indexFirstName);
}

如果你不知道列的索引,但不想检查一个名称,你可以使用这个扩展方法:

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;
    }
}

然后像这样使用方法:

if(sqlReader.HasColumn("FirstName"))
{
  employee.FirstName = sqlreader["FirstName"];
}

作为marc_s答案的补充,你可以使用一个更通用的扩展方法从SqlDataReader中获取值:

public static T SafeGet<T>(this SqlDataReader reader, int col)
    {
        return reader.IsDBNull(col) ? default(T) : reader.GetFieldValue<T>(col);
    }

我们使用一系列静态方法从数据读取器中提取所有值。创建静态/共享方法的好处是,你不必一遍又一遍地做同样的检查…

静态方法将包含检查空值的代码(参见本页的其他答案)。

如何创建帮助方法

为字符串

private static string MyStringConverter(object o)
    {
        if (o == DBNull.Value || o == null)
            return "";

        return o.ToString();
    }

使用

MyStringConverter(read["indexStringValue"])

为整数

 private static int MyIntonverter(object o)
    {
        if (o == DBNull.Value || o == null)
            return 0;

        return Convert.ToInt32(o);
    }

使用

MyIntonverter(read["indexIntValue"])

为日期

private static DateTime? MyDateConverter(object o)
    {
        return (o == DBNull.Value || o == null) ? (DateTime?)null : Convert.ToDateTime(o);
    }

使用

MyDateConverter(read["indexDateValue"])

注意:对于DateTime声明变量为

DateTime? variable;
employee.FirstName = sqlreader[indexFirstName] as string;

对于整数,如果转换为可空整型,则可以使用GetValueOrDefault()

employee.Age = (sqlreader[indexAge] as int?).GetValueOrDefault();

或者空合并操作符(??)。

employee.Age = (sqlreader[indexAge] as int?) ?? 0;