如何将数据库中的null值检索到视图

本文关键字:检索 视图 null 数据库 | 更新日期: 2023-09-27 18:21:17

我有一个简单的员工数据库,它允许我添加新的员工,其中一些文本框字段为空(我使用的是winform)。它目前在数据库中运行良好。它注册NULL值来代替空文本框。我现在的问题是如何在网格视图中显示数据库中的所有员工:当我运行程序时,它会弹出一个消息框,上面写着"对象不能从DBNull转换为其他类型"。是因为我的数据库中的"年龄"answers"已婚"列包含一些空值吗?请帮忙,我正在尝试了解如何在带有mssql数据库的c#中使用可为null的类型。

   public static List<Employee> GetEmployees()
    {
        List<Employee> empListToReturn = new List<Employee>();
        SqlConnection conn = GetConnection();
        string queryStatment = "SELECT * FROM Employee";
        SqlCommand sqlCmd = new SqlCommand(queryStatment, conn);
        try
        {
            conn.Open();
            SqlDataReader reader = sqlCmd.ExecuteReader();
            while (reader.Read())
            {
                Employee emp = new Employee();
                emp.FirstName = reader["firstname"].ToString();
                emp.LastName = reader["lastname"].ToString();
                emp.Age = Convert.ToInt32(reader["age"]);
                emp.Married = (reader["married"]);
                empListToReturn.Add(emp);
            }
            reader.Close();
        }
        catch (SqlException ex)
        {
            throw ex;
        }
        finally
        {
            conn.Close();
        }
        return empListToReturn;
    }

如何将数据库中的null值检索到视图

由于错误状态,您无法将null转换为其他类型。特别是在这种情况下,int:

emp.Age = Convert.ToInt32(reader["age"]);

(由于值类型不能是null。)

转换前只需检查null

if (reader["age"] == DBNull.Value)
    emp.Age = 0;
else
    emp.Age = Convert.ToInt32(reader["age"]);

编辑:正如评论中所指出的,有多种方法可以做到这一点。有些可能比其他人更有效率。例如:

if (reader.IsDBNull(reader.GetOrdinal("age")))
    emp.Age = 0;
else
    emp.Age = reader.GetInt32(reader.GetOrdinal("age")));

除非性能差异很大,否则在使用命名列而不是序数时,我可能更喜欢前者,因为这需要额外的方法调用来获取序数。(除非我在MSDN上没有看到字符串过载?)


此外,如果不希望0作为选项,可以将.Age属性从int更改为Nullable<int>(简称int?)。这将允许您在该对象上设置null值:

if (reader.IsDBNull(reader.GetOrdinal("age")))
    emp.Age = null; // <-- here
else
    emp.Age = reader.GetInt32(reader.GetOrdinal("age")));

0(有效值)和null(缺少值)之间存在明显的语义差异时,这通常非常有用。


同样值得注意的是,此代码是一种糟糕的做法:

catch (SqlException ex)
{
    throw ex;
}

您的catch块不仅根本没有处理异常,而且实际上正在覆盖堆栈跟踪。这将使调试更加困难。由于catch块没有执行任何操作,只需将其完全删除即可。try/finally中不需要catch