我试图将datagridview行中的数据保存到sql数据库中。我的问题是我当前的代码,它读取并更新所有行,无论是否有任何更改。我知道这将是一个问题,尤其是当我的表有大量数据时。
以下是我目前对代码所做的工作:
//retrieve data from dbase
public void loadToDGV()
{
DBConn.DBConnect();
SqlDataAdapter sqlDA = new SqlDataAdapter("SELECT * from TableName", DBConnection.conn);
sqlDA.Fill(dataTable);
gridView.DataSource = dataTable;
}
下面是我的“保存”按钮中的内容。
foreach (DataGridViewRow row in gridView.Rows)
{
DBConn.DBConnect();
SqlCommand comm = new SqlCommand();
comm.Connection = DBConnection.conn;
comm = new SqlCommand("SPName", DBConnection.conn);
comm.CommandType = CommandType.StoredProcedure;
comm.Parameters.AddWithValue("@ID", row.Cells["ID"].Value == DBNull.Value ? "" : row.Cells["ID"].Value);
comm.ExecuteNonQuery();
}
我有另一个示例代码,其中我只能保存修改的行
changeTable = dataTable.GetChanges(DataRowState.Modified);
foreach (DataRow row in changeTable.Rows)
{
DBConn.DBConnect();
SqlCommand comm = new SqlCommand();
comm.Connection = DBConnection.conn;
comm = new SqlCommand("SPName", DBConnection.conn);
comm.CommandType = CommandType.StoredProcedure;
comm.Parameters.AddWithValue("@ID", row["ID"].ToString());
comm.ExecuteNonQuery();
}
我想做的是只保存BOTH“New Rows”AND“Modified Rows”。有没有办法只获取新添加/编辑的行?而不包括网格视图中的所有行?
我的存储过程只检查ID是否存在。
- 如果不存在(从ID = @ID的表中选择1)--插入查询 *
- 否则--更新查询 *
1条答案
按热度按时间svmlkihl1#
您根本不应该使用循环,甚至不应该引用网格。显然您已经有了一个
DataTable
。如果您还没有这样做,请用数据适配器填充它,将它绑定到BindingSource
并将其绑定到网格。当需要保存时,在BindingSource
上调用EndEdit
,在数据适配器上调用Update
,并传递DataTable
。就这样,就这样。没有必要调用GetChanges
。显然,您必须正确地配置数据适配器,使用
InsertCommand
插入新记录,使用UpdateCommand
保存修改过的记录。由于您还没有详细说明,因此我不会详细说明,但是有很多示例。您可以找到我自己的here。编辑:
您的问题的简短答案是,如果您想要修改和新增的数据列,请同时指定
Modified
和Added
数据列。DataRowState
枚举型别具有Flags
属性,这表示您可以建立复合值。这表示:会变成这样:
如果要循环遍历这些行,就不必每次迭代都创建一个新的命令对象,只需创建一个命令并添加一次参数,然后在循环中设置每个参数的
Value
即可,之后还需要在原始的DataTable
上调用AcceptChanges
。正如我所说的,您应该使用与检索数据相同的数据适配器来保存更改。通常,您会对
InsertCommand
和UpdateCommand
使用不同的SQL,但是,在您的情况下,只需创建一个带有适当参数的命令对象,并将其分配给InsertCommand
和UpdateCommand
属性,然后调用Update
。