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

employee.FirstName = sqlreader.GetString(indexFirstName);

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


当前回答

这个方法依赖于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"];
}

其他回答

这个方法依赖于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"];
}

我想你会想用:

SqlReader.IsDBNull(indexFirstName)

你需要检查IsDBNull:

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

这是检测和处理这种情况的唯一可靠方法。

我把这些东西包装到扩展方法中,如果列确实为空,则倾向于返回默认值:

public static string SafeGetString(this SqlDataReader reader, int colIndex)
{
   if(!reader.IsDBNull(colIndex))
       return reader.GetString(colIndex);
   return string.Empty;
}

现在你可以这样调用它:

employee.FirstName = SqlReader.SafeGetString(indexFirstName);

而且您再也不用担心异常或空值了。

if(reader.IsDBNull(ColumnIndex)) {// logic}就像许多答案所说的那样。

我想提一下,如果你使用列名,比较类型可能会更舒服。

if(reader["TeacherImage"].GetType() == typeof(DBNull)) { //logic }

我倾向于用合适的东西替换SELECT语句中的空值。

SELECT ISNULL(firstname, '') FROM people

在这里,我将每个null替换为一个空白字符串。在这种情况下,代码不会抛出错误。