为什么必须为非查询打开连接但不填充数据集?

时间:2012-05-16 14:22:37

标签: c# sql windows database-connection

当我连接到C#应用程序中的SQL数据源时,我可以使用以下代码填充数据集。请注意,我没有明确地打开与数据源的连接。

SqlConnection cw_con = new SqlConnection("Server=Server;Database=Database;User=User;password=password");
SqlCommand cmd = new SqlCommand("SELECT * FROM Example WHERE value = value");
cmd.Connection = cw_con;

//Create DataSet
DataSet cw_ds = new DataSet("cw_ds");
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = cmd;
//Execute Command and Fill DataSet
da.Fill(cw_ds);
cw_ds.Clear();

但是,如果我想执行诸如INSERT INTOUPDATE之类的非查询,为什么我必须使用connection.Open();明确打开连接?

SqlConnection cw_con = new SqlConnection("Server=Server;Database=Database;User=User;password=password");
cw_con.Open();
SqlCommand cmd = new SqlCommand("UPDATE example SET value = value WHERE value = value");
cmd.Connection = cw_con;
cmd.ExecuteNonQuery();
cw_con.Close();

3 个答案:

答案 0 :(得分:3)

来自DataAdapter.Fill文档

  

如果在调用Fill之前关闭了连接,则会打开它   检索数据,然后关闭。如果连接在Fill之前打开   叫它,它仍然是开放的。

当您使用SqlCommand时,您正在使用较低级别的类,因此您需要自己管理连接。

这是一个用例,你不希望自动打开连接,因为它会多次打开和关闭,最好只是抛出异常

SqlCommand InsertCmd = new ("Insert statement", cw_con)

cw_con.Open();

foreach (var newitem in collection)
{
   --Set Parameters
   UpdateCmd.ExecuteNonQuery();
}

cw_con.Close();

答案 1 :(得分:3)

这是因为DataAdapter在最初关闭时会隐式打开连接。如果以前关闭它会关闭它,否则连接会保持打开状态。

来自MSDN

  

Fill方法使用SELECT从数据源检索数据   声明。与select命令关联的IDbConnection对象   必须有效,但不需要打开。如果是IDbConnection   在调用Fill之前关闭它,它被打开以检索数据和   然后关闭如果在调用Fill之前连接已打开,则为   仍然开放。

使用SqlCommand时,您必须自己明确地打开和关闭连接。

作为旁注

  1. 使用parameters来避免SQL注入
  2. 使用using-statement来实现IDisposable,尤其是连接,因为它可以确保尽快处理/关闭,即使出现错误

答案 2 :(得分:2)

文档说明了

  

Fill方法使用SELECT从数据源中检索行   由关联的SelectCommand属性指定的语句。该   与SELECT语句关联的连接对象必须有效,   但它不需要打开。如果之前连接已关闭   调用Fill,打开它以检索数据,然后关闭。如果   在调用Fill之前连接已打开,它仍保持打开状态。

查看here了解更多信息。