为什么必须为非查询打开连接,而不是填充数据集

本文关键字:数据集 填充 连接 查询 为什么 | 更新日期: 2023-09-27 18:34:25

当我在 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();

为什么必须为非查询打开连接,而不是填充数据集

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

从 MSDN:

Fill 方法使用 SELECT 从数据源检索数据 陈述。与选择命令关联的 IDbConnection 对象 必须有效,但不需要打开。如果 IDb连接 在调用 Fill 之前关闭,打开它以检索数据,并且 然后关闭。如果在调用 Fill 之前连接已打开,则 保持开放状态。

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

作为旁注

  1. 使用参数避免 SQL 注入
  2. 将 using-语句用于任何实现IDisposable,尤其是连接,因为它确保它尽快被释放/关闭,即使在出现错误的情况下也是如此

来自 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();

文档指出

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

查看此处以获取更多信息。