这样写这个辅助方法是否安全?它会不会关闭连接?我想知道如果一切顺利,它会,但是即使它抛出,ExecuteReader也会关闭连接吗?
public static IEnumerable<DbDataRecord> ExecuteSelect(string commandText, DbConnection conn)
{
using (DbCommand cmd = conn.CreateCommand())
{
cmd.CommandText = commandText;
conn.Open();
using (DbDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
{
foreach (DbDataRecord record in reader) { yield return record; }
}
}
}
答案 0 :(得分:8)
是的,即使它抛出异常也会关闭连接。
如果您未指定CommandBehavior.CloseConnection
并关闭连接,则您的主叫代码无法访问阅读器的内容。
同样来自MSDN:
执行命令时,关联的Connection对象是 关闭关联的DataReader对象时关闭。
完成后,您应该确保阅读器已关闭。
关于所有这一切的好处是你已经将它包含在一个using语句中并且你没有使用try/catch/finally
在这种情况下读者将被关闭然后关闭数据库连接。
答案 1 :(得分:2)
我个人更喜欢使用using子句关闭/处理连接,仅仅是出于并行构造的原因 - 与良好的英语语法相同。使用CommandBehavior
对我来说是不平衡的,因此是不可预测的。
我告诉我的开发人员要简单,一致。如果他们忘记设置命令行为,我将不会看到它。如果他们不使用使用 ......我会看到它。
答案 2 :(得分:0)
是的它(在你正在做的使用区内)。但要访问您可能想要使用的数据,而不是迭代其内容。
DbDataReader.read。答案 3 :(得分:0)
我知道问题与关闭连接有关;但是,连接不会被处理掉。要自行处理连接,您还需要将using
块括起来:
using (DBConnection conn = new ...)
{
using (DbCommand cmd = conn.CreateCommand())
{
cmd.CommandText = commandText;
conn.Open();
using (DbDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
{
foreach (DbDataRecord record in reader) { yield return record; }
}
}
}
更新我认为这是一个有趣的问题所以我写了以下测试:
string connString = @"Data Source=.\SQLEXPRESS;Initial Catalog=msdb;Integrated Security=True;";
SqlConnection conn = new SqlConnection(connString);
try
{
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "select from MSdbms";
conn.Open();
Console.WriteLine(conn.State);
using (IDataReader reader = cmd.ExecuteReader())//Will throw an exception - Invalid SQL syntax -see setting CommandText above
{
Console.WriteLine("here");
}
}
}
catch(Exception ex)
{ Console.WriteLine(conn.State); } //prints Open
如果行using (IDataReader reader = cmd.ExecuteReader())
更改为:using (DbDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
,则会打印已关闭。要记住的事情。
答案 4 :(得分:0)
如果您关闭阅读器和/或用using(var reader ...){}
阻止是包裹阅读器,请确保您的连接已关闭。
没有包装,并且没有reader.Close()
关闭阅读器保持我的连接打开。