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

employee.FirstName = sqlreader.GetString(indexFirstName);

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


当前回答

employee.FirstName = sqlreader[indexFirstName] as string;

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

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

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

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

其他回答

employee.FirstName = sqlreader[indexFirstName] as string;

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

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

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

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

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

SELECT ISNULL(firstname, '') FROM people

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

您可以编写一个通用函数来检查Null,并在它为Null时包含默认值。读取Datareader时调用此函数

public T CheckNull<T>(object obj)
        {
            return (obj == DBNull.Value ? default(T) : (T)obj);
        }

读取Datareader时使用

                        while (dr.Read())
                        {
                            tblBPN_InTrRecon Bpn = new tblBPN_InTrRecon();
                            Bpn.BPN_Date = CheckNull<DateTime?>(dr["BPN_Date"]);
                            Bpn.Cust_Backorder_Qty = CheckNull<int?>(dr["Cust_Backorder_Qty"]);
                            Bpn.Cust_Min = CheckNull<int?>(dr["Cust_Min"]);
                         }

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

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

我尽了最大努力从DataTable中重新实现Field方法。https://learn.microsoft.com/en-us/dotnet/api/system.data.datarowextensions.field

如果您尝试转换DBNull,它将抛出。值转换为非空类型。否则它将转换为DBNull。值为null。

我还没有完全测试过。

public static T Field<T>(this SqlDataReader sqlDataReader, string columnName)
{
    int columnIndex = sqlDataReader.GetOrdinal(columnName);
    if (sqlDataReader.IsDBNull(columnIndex))
    {
        if (default(T) != null)
        {
            throw new InvalidCastException("Cannot convert DBNULL value to type " + typeof(T).Name);
        }
        else
        {
            return default(T);
        }
    }
    else
    {
        return sqlDataReader.GetFieldValue<T>(columnIndex);
    }
}

用法:

string fname = sqlDataReader.Field<string>("FirstName");
int? age = sqlDataReader.Field<int?>("Age");
int yearsOfExperience = sqlDataReader.Field<int?>("YearsEx") ?? 0;