关闭datareader时出现NullReferenceException

时间:2013-02-25 14:57:07

标签: c# .net ado.net

我正在学习使用ADO.NET,我似乎遇到了问题。我想要做的是从表中获取数据并将其插入到DataTable中。这是我的代码:

public DataTable GetCategories()
    {
        SqlConnection connection = null;
        SqlDataReader reader = null;
        DataTable categories = new DataTable();

        try {
            connection = new SqlConnection();
            connection.ConnectionString = connectionString;
            connection.Open();

            SqlCommand cmd = new SqlCommand();
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.CommandText = "GetCategories";
            reader = cmd.ExecuteReader();

            categories.Columns.Add("Id", typeof(int));
            categories.Columns.Add("CategoryName", typeof(int));

            while (reader.Read()) {
                int categoryId = (int)reader["Id"];
                string categoryName = (string)reader["CategoryName"];
                categories.Rows.Add(categoryId , categoryName);
            }

        }catch(Exception e){
            DataTable error = new DataTable();
            error.Columns.Add("Error");
            error.Rows.Add(e.Message);
            return error;
        }finally{
            connection.Close();
            reader.Close();
        }
        return categories;
    }

这是我的SQL查询:

 CREATE PROCEDURE [dbo].[GetCategories]
    AS
        SELECT Id , CategoryName
        FROM Categories

在我运行此方法的地方,我回到了reader.Close()上,这是一个NullRefferenceException的异常。

我做错了什么?

修改

我刚注意到reader = cmd.ExecuteReader();抛出InvalidOperationException。这是因为查询?

3 个答案:

答案 0 :(得分:7)

您编写代码的方式意味着如果创建或连接到SqlConnection时出错,则您的finally块将尝试关闭尚未设置的reader

检查finally块中的空值或重新构造代码。

答案 1 :(得分:1)

您需要检查null阻止中的finally引用:

    finally{
        connection.Close();
        if (reader != null)
          reader.Close();
    }

如果您的SqlConnectionconnection.Open()时引发异常,则系统不会初始化阅读器,其值为null,因此您需要在finally块中进行检查。

答案 2 :(得分:1)

SqlCommand需要访问SqlConnection对象。 E.g:

SqlCommand cmd = new SqlCommand("dbo.GetCategories", connection)

另外,请查看using block - 这是构建数据访问代码的更好方法。