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

时间:2015-11-10 13:19:24

标签: c# sql-server winforms

我有一个简单的员工数据库,它允许我添加一个新员工,我的一些文本框字段留空(我正在使用winform)。它目前在数据库中正常工作。它注册NULL值代替空文本框。我现在的问题是如何在gridview中显示数据库中的所有员工: 当我运行该程序时,它弹出一个消息框,说“对象无法从DBNull转换为其他类型”。是因为我的数据库中的'age'和'married'列包含一些空值?请帮助,我正在尝试了解如何在c#中使用可空类型与mssql数据库。

   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;

    }

1 个答案:

答案 0 :(得分:1)

如错误所述,您无法将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块无法执行任何操作,因此请完全删除它。您不需要catch中的try/finally