首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >返回SqlDataReader

返回SqlDataReader
EN

Stack Overflow用户
提问于 2013-05-09 18:16:52
回答 4查看 2.4K关注 0票数 2

我正试图以参考的方式传递一位读者或让一位读者返回。我在回来的时候对它有意见。

代码语言:javascript
复制
public static SqlDataReader GetSql(string businessUnit, string taskId)
{
            const string connstring = "Connection string";
            SqlConnection conn = new SqlConnection(connstring);
            SqlCommand command = new SqlCommand();
            SqlDataReader reader;
            try
            {
                conn.Open();
                command.Connection = conn;
                command.CommandType = CommandType.Text;
                command.CommandText =
                    "SELECT * FROM Audits WHERE BusinessUnit = @BU AND TaskID = @TID";
                command.Parameters.AddWithValue("@BU", businessUnit);
                command.Parameters.AddWithValue("@TID", taskId);
                return reader = command.ExecuteReader(CommandBehavior.CloseConnection);
            }
            catch (Exception ex)
            {
                return null;
            }
            finally
            {
                conn.Close();
            }
}


SqlDataReader reader = QaqcsqlLib.GetSql("job", "Task1");

if (reader.HasRows)
{
   while (reader.Read())
      MessageBox.Show(reader[0].ToString());
}

但是我得到了以下错误

关闭读取器时调用HasRows的尝试无效。

有什么想法吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-05-09 18:18:46

这就是问题所在:

代码语言:javascript
复制
finally
{
    conn.Close();
}

在方法返回之前关闭连接。如果没有打开的连接,读者将无法正常工作。

(考虑到只有在返回时才使用reader变量,所以不清楚为什么要使用它。)

在打开连接的方法中返回SqlDataReader通常很棘手,因为这意味着您没有一种很好的关闭连接的方法。最好是让调用方传入连接,此时您可以拥有:

代码语言:javascript
复制
using (var connection = new SqlConnection(...))
{
    using (var reader = QaqcsqlLib.GetSql(connection, "job", "Task1"))
    {
        // Use the reader here
    }
}

编辑:正如Scott所指出的,使用CommandBehavior.CloseConnection将允许关闭读取器以关闭连接。然而,它使其他事情变得更加棘手。例如,如果出现异常(因为调用方将没有机会),则必须释放连接,但不是其他--我仍然更喜欢我的方法。

票数 12
EN

Stack Overflow用户

发布于 2013-05-09 19:01:29

约翰是对的关于为什么会出现问题,但不需要传递连接。

我可以看到,在启动读取器并传入SqlCommand.ExecuteReader(CommandBehavior)时,您已经在使用CommandBehavior.CloseConnection重载。然而,您所做的错误是您从未处理从您的函数返回的读取器。删除finally块,然后将返回的读取器包装到using块中。这将在退出块时为您关闭底层连接(因为您在CommandBehavior.CloseConnection中传递)。

代码语言:javascript
复制
using(SqlDataReader reader = QaqcsqlLib.GetSql("job", "Task1"))
{
    while (reader != null && reader.Read()) //Added null check as your GetSql could return null.
      MessageBox.Show(reader[0].ToString());
}

我还去掉了reader.HasRows,因为它是不必要的。如果没有返回的结果,那么对reader.Read()的第一次调用将返回false,并且while循环中的代码将永远不会执行。

当出现异常时,仍然需要关闭连接,但是可以将关闭从finally in移到catch。

代码语言:javascript
复制
catch (Exception ex)
{
    conn.Dispose(); //Disposing closes the connection.
    return null;
}
票数 4
EN

Stack Overflow用户

发布于 2013-05-09 18:20:20

您可以尝试遵循下一个示例http://msdn.microsoft.com/en-us/library/haa3afyz.aspx

在使用您的读取器之前,不应该调用close方法。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16468379

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档