我正在使用 SQLdatareader 从数据库中构建 POCOs。代码运行良好,除非在数据库中遇到空值。例如,如果数据库中的 FirstName 列包含空值,将抛出异常。
employee.FirstName = sqlreader.GetString(indexFirstName);
如何在这种情况下处理空值?
我正在使用 SQLdatareader 从数据库中构建 POCOs。代码运行良好,除非在数据库中遇到空值。例如,如果数据库中的 FirstName 列包含空值,将抛出异常。
employee.FirstName = sqlreader.GetString(indexFirstName);
这是一个帮助类,如果其他人需要,可以基于@marc_s的答案使用:
public static class SQLDataReaderExtensions
{
public static int SafeGetInt(this SqlDataReader dataReader, string fieldName)
{
int fieldIndex = dataReader.GetOrdinal(fieldName);
return dataReader.IsDBNull(fieldIndex) ? 0 : dataReader.GetInt32(fieldIndex);
}
public static int? SafeGetNullableInt(this SqlDataReader dataReader, string fieldName)
{
int fieldIndex = dataReader.GetOrdinal(fieldName);
return dataReader.GetValue(fieldIndex) as int?;
}
public static string SafeGetString(this SqlDataReader dataReader, string fieldName)
{
int fieldIndex = dataReader.GetOrdinal(fieldName);
return dataReader.IsDBNull(fieldIndex) ? string.Empty : dataReader.GetString(fieldIndex);
}
public static DateTime? SafeGetNullableDateTime(this SqlDataReader dataReader, string fieldName)
{
int fieldIndex = dataReader.GetOrdinal(fieldName);
return dataReader.GetValue(fieldIndex) as DateTime?;
}
public static bool SafeGetBoolean(this SqlDataReader dataReader, string fieldName)
{
return SafeGetBoolean(dataReader, fieldName, false);
}
public static bool SafeGetBoolean(this SqlDataReader dataReader, string fieldName, bool defaultValue)
{
int fieldIndex = dataReader.GetOrdinal(fieldName);
return dataReader.IsDBNull(fieldIndex) ? defaultValue : dataReader.GetBoolean(fieldIndex);
}
}
DataTable
的Field
方法。 https://learn.microsoft.com/en-us/dotnet/api/system.data.datarowextensions.field
如果您尝试将DBNull.Value
转换为非可空类型,它将抛出异常。否则,它将DBNull.Value
转换为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;
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"];
}
旧问题,但可能仍有人需要答案
实际上,我是这样解决这个问题的
对于int类型:
public static object GatDataInt(string Query, string Column)
{
SqlConnection DBConn = new SqlConnection(ConnectionString);
if (DBConn.State == ConnectionState.Closed)
DBConn.Open();
SqlCommand CMD = new SqlCommand(Query, DBConn);
SqlDataReader RDR = CMD.ExecuteReader();
if (RDR.Read())
{
var Result = RDR[Column];
RDR.Close();
DBConn.Close();
return Result;
}
return 0;
}
int TotalPoints = GatDataInt(QueryToGetTotalPoints, TotalPointColumn) as int?;
并且
string Email = GatDatastring(QueryToGetEmail, EmailColumn) as string;
可以使用三元运算符进行赋值:
employee.FirstName = rdr.IsDBNull(indexFirstName))?
String.Empty: rdr.GetString(indexFirstName);
根据每个属性类型适当地替换默认值(当为null时)...
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();
}
if (!reader.IsDBNull(2))
{
row["Oracle"] = (string)reader[2];
}
简洁的一行代码:
while (dataReader.Read())
{
employee.FirstName = (!dataReader.IsDBNull(dataReader.GetOrdinal("FirstName"))) ? dataReader["FirstName"].ToString() : "";
}
合理地处理 DbNull 的句柄。
employee.FirstName = Convert.ToString(sqlreader.GetValue(indexFirstName));
if(null !=x && x.HasRows)
{ ....}
SqlDataReader
的情况。 - bluish