【问题标题】:How do I properly use a SqlDataReader?如何正确使用 SqlDataReader?
【发布时间】:2013-08-10 07:01:40
【问题描述】:

我有以下两种方法:

internal static SqlDataReader SelectData(string sql)
{
    using (var sqlConnection = new SqlConnection(Constant.ConnectionString))
    {
        sqlConnection.Open();
        var sqlCommand = new SqlCommand(sql, sqlConnection);
        var dataReader = sqlCommand.ExecuteReader();
        return dataReader;
    }
}

============

并将此方法用作:

var dataReader = SelectData(---some sql ---);

private void AddData(dataReader)
{
    while (dataReader.Read())
    {
        Employee e = new Employee();
        e.FirstNamei = dataReader["Name"].ToString();
    }

    dataReader.Close();
}

我知道我们可以合并这两种方法,但我正在寻找更好的方法来写这个,或者这会导致一些问题??

【问题讨论】:

  • 您提到您在第二种方法中使用了第一种方法,但事实并非如此。这两种方法似乎彼此无关,所以你的问题仍然不清楚。顺便说一句,never use empty catch-blocks.
  • @TimSchmelter .. 没错..我编辑了..
  • 为什么不使用企业库进行数据访问?
  • @T.S. - 我很惊讶Enterprise Library 仍然保持不变。以前叫shiznit,好久没听说了。
  • 不只是维护。它最近有新版本。它比 EF 运行得更快,并且具有缓存功能。我认为,比在每个页面上创建连接更值得实施。

标签: c# .net ado.net


【解决方案1】:

实际上,您实际上是在让自己敞开心扉。你真的想这样写:

using (SqlConnection cnn = new SqlConnection(cnnString))
using (SqlCommand cmd = new SqlCommand(sql, cnn))
{
    // use parameters in your SQL statement too, so you can do this
    // and protect yourself from SQL injection, so for example
    // SELECT * FROM table WHERE field1 = @parm1
    cmd.Parameters.AddWithValue("@parm1", val1);

    cnn.Open();
    using (SqlDataReader r = cmd.ExecuteReader())
    {

    }
}

因为您需要确保这些对象得到处置。此外,通过这个方向,您不需要dataReader.Close()。当它被using 语句自动释放时,它将被调用。

现在,将这组语句包装在 try...catch 中,您就可以开始工作了。

【讨论】:

  • 我只是想重构它..这样我就可以在任何地方使用像SelectData 这样的方法..你给的是一个很棒的工作代码..
  • 为了清楚起见,第一组大括号是不必要的。 using(SqlConnection cnn = n.....) using(SqlCommand cmd = n.....) { // 代码 } 只是节省了这么多的嵌套。使用语句可以背靠背
  • @Hawxby,我不确定我是否关注。
  • 我已提交修改。您可以在每个语句之间使用不带大括号的 using 语句 using() using() using () {}
  • @Hawxby,不错的小语法糖。感谢补充
【解决方案2】:

几件事

1) 由于您要关闭 SelectData 上的连接,dataReader 应该会在 AddData 上爆炸,因为它需要打开连接

2) AddData 不应该关闭 dataReader,因为他没有打开它。

3) 也许您隐藏了一些代码,但我没有看到您使用在 AddData 上创建的 Employee 实例

【讨论】:

  • 也就是说,我在 AddData 方法中访问时,datareader 是空白的??
  • @Ratan: 不是空白,它应该抛出一个错误,因为连接不再活跃。
  • 在某个地方,我可以看到一些理想的方法来编写这种类型的方法。因为对于每种类型的Employee e = new Employee();,我都需要一次又一次地写整个事情。跨度>
【解决方案3】:

从技术上讲,如果你愿意,第一种方法是正确的

    sqlCommand.ExecuteReader(CommandBehavior.CloseConnection);

然后,您的客户端将关闭阅读器,您的连接也将关闭。

如果您没有关闭其中的阅读器,第二个示例也是正确的。将读者传递给一个方法只是为了迭代它,这并没有犯罪。但必须从创建它的地方对其进行控制。您如何打开和处理它 - 这是不同的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-05
    • 2023-03-20
    • 2011-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多