转换C#之前检查DbNull

时间:2018-10-11 02:20:32

标签: c# asp.net sql-server asp.net-web-api sqlconnection

我正在尝试查询SQL Server数据库并以JSON返回响应。我正在尝试下面的代码

      using (SqlConnection connection = new SqlConnection(connStr))
        {
            SqlCommand command = new SqlCommand(commandText, connection);
            command.Parameters.Add("@ROOM_Data", SqlDbType.VarChar);
            command.Parameters["@ROOM_Data"].Value = ROOM;
            connection.Open();
            List<DatabaseResult> records = new List<DatabaseResult>();

            using (var reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    var row = new DatabaseResult
                    {
                        request_id = (int)reader["request_id"],
                        room = (string)reader["room"],
                        jrs_no = (int)reader["jrs_no"],
                        submit_date = (DateTime)reader["submit_date"],
                        sample_no = (int)reader["sample_no"],
                        animal_id = (string)reader["animal_id"],
                        pen_id = (string)reader["pen_id"],
                        ped_no = (string)reader["ped_no"],
                        gender = (string)reader["gender"],
                        dob = (DateTime)reader["dob"],
                        parent_mating = (string)reader["parent_mating"],
                        generation = (string)reader["generation"],
                        allele = (string)reader["allele"],
                        status_type = (string)reader["status_type"],
                        genotype = (string)reader["genotype"],
                        comments = (string)reader["comments"],
                        completion_date = (DateTime)reader["completion_date"],
                        disposition = (string)reader["disposition"],

                    };
                    records.Add(row);
                }
                return Ok(records);

在这里,任何字段中都为null时,我遇到问题。我尝试查看其他论坛,我了解我们是否需要在投射前检查每列是否为空。但是我正在检查是否可以通过能够处理所有情况的方法来做到这一点?

7 个答案:

答案 0 :(得分:5)

您可以像这样检查DBNull.Value的列值:

request_id = (reader["request_id"] == DBNull.Value) ? default(int) : (int)reader["request_id"];

如果要将流程简化为所有列,请创建一个扩展方法,将其与DBNull.Value进行比较,如下例所示:

// using DBNull.Value comparison
public static T GetValue<T>(this SqlDataReader reader, string columnName)
{
    var value = reader[columnName]; // read column value

    return value == DBNull.Value ? default(T) : (T)value;
}

// alternative using GetOrdinal and IsDBNull
public static T GetValue<T>(this SqlDataReader reader, string columnName) 
{
    int index = reader.GetOrdinal(columnName); // read column index

    return reader.IsDBNull(index) ? default(T) : (T)reader.GetValue(index);
}

用法示例:

request_id = GetValue<int>(reader, "request_id");

答案 1 :(得分:2)

尝试这样

public static class SqlReaderExtention {

     public static T GetValue<T>(this SqlDataReader reader, string fieldName) {
        int columnIndex = reader.GetOrdinal(fieldName);
        if (reader.IsDBNull(columnIndex)) {
           return default(T);
        }

        return (T)reader.GetValue(columnIndex);
     }
 }

答案 2 :(得分:0)

一个问题是int在转换时不处理空值。

尝试

sample_no = (int?)reader["sample_no"]

以及您的课程DatabaseResult

sample_no声明为int? sample_no

int?表示其可为null的int,如果您将null值传递给它,则不会引发异常。

另一种方法是int.TryParse,如果它检测到它为空值,它将放置0。

答案 3 :(得分:0)

如果必须使用数据读取器,并且正在定义自己的原始sql,这似乎是这种情况,则可以在sql中包装修改sql语句,以在select部分中使用ISNULL检查。 例如-确保返回一个字符串列,并使用空字符串('')而不是NULL

select isnull(foo,'') from myTable

答案 4 :(得分:0)

request_id = reader["request_id"] == DBNull.Value ? null : (int?)reader["request_id"] ,
room = reader["room"].ToString(),
jrs_no = reader["jrs_no"] == DBNull.Value ? null : (int?)reader["jrs_no"] ,
submit_date = reader["submit_date"] == DBNull.Value ? null : (DateTime?)reader["submit_date"],
sample_no = reader["sample_no"] == DBNull.Value ? null : (int?)reader["sample_no"],
animal_id = reader["animal_id"].ToString(),
pen_id = reader["pen_id"].ToString(),
ped_no = reader["ped_no"].ToString(),
gender = reader["gender"].ToString(),
dob = reader["dob"] == DBNull.Value ? null : (DateTime?)reader["dob"],
parent_mating = reader["parent_mating"].ToString(),
generation = reader["generation"].ToString(),
allele = reader["allele"].ToString(),
status_type = reader["status_type"].ToString(),
genotype = reader["genotype"].ToString(),
comments = reader["comments"].ToString(),
completion_date = reader["completion_date"] == DBNull.Value ? null : (DateTime?)reader["completion_date"],
disposition = reader["disposition"].ToString(),
您可以根据需要管理

数据库空值。 int和datetime变量更改为int?和日期时间?分别设置,或者您可以设置默认值,以防db值为空

答案 5 :(得分:0)

您必须小心地将int解析为代码,因为它可能会返回错误。

为什么不尝试在后面的代码中运行它并使用isnull在查询中对其进行修复。

select isnull(yourNumField,'0')

答案 6 :(得分:0)

虽然我同意针对一般用途提到的扩展方法选项,但如果您只需要快速检查 DB Null 中可能为 null 的值,我会推荐以下内容:

if (rdr["request_id"] != DBNull.Value)
   RequestID = Convert.ToInt32(rdr["request_id"]);

或者,您可以更简洁,并提供一个默认值:

RequestID = (rdr["request_id"] != DBNull.Value) ? Convert.ToInt32(rdr["request_id"]) : 0;