获取已更改的 DataTable
考虑一种情况,您有一个数据网格,其中所有或大部分行都处于可编辑模式。
引言
考虑一种情况,您有一个数据网格,其中所有或大部分行都处于可编辑模式。您更改了`datagrid`中的一个项目,然后按下保存按钮。您很可能将所有数据发送到数据库以进行更新。如果发送了数千行,这对于性能来说可能非常糟糕,因为我们只更改了一行,因此只有这一行应该发送到 DAL 层以执行更新。在本文中,我们将看到如何仅从`datatable`对象获取已更改的行。
背景
设置用户界面
用户界面非常简单。
我有三列,分别是`UserID`、`UserName`和`Score`。这些列是使用“属性构建器”创建的(在设计视图中右键单击`DataGrid`控件并选择属性构建器)。如果您想动态创建您的列,请查看我的文章,在数据网格中动态创建绑定列和模板列。
正如您所看到的,`score`是一个“`TextBox`”列,它将允许我们进行更改。当我们按下“获取已更改的行”按钮时,我们将仅获取已更改的行。
BindGrid 方法
`BindGrid`方法在没有回传时被调用。
private void BindData()
{
Database db = DatabaseFactory.CreateDatabase();
DBCommandWrapper selectCommandWrapper = db.GetStoredProcCommandWrapper("GetGrades");
oldDataSet = db.ExecuteDataSet(selectCommandWrapper);
DataGrid1.DataSource = oldDataSet;
DataGrid1.DataBind();
// Put the DataSet in the session object
Session["DataSet"] = oldDataSet;
}
最重要的一行是加粗的一行,我在其中将`oldDataSet`分配给`Session`对象,这样我就可以拥有`DataSet`的副本。
Using the Code
按钮点击代码(获取更改)
仅从`datagrid`获取已更改值的核心思想很简单。我们获取旧的`DataSet`。我们从`oldDataSet`中创建一个`DataTable`对象。我们循环遍历`Datagrid`并检索每一行的值。我们使用主键分配`oldDataTable`,在这种情况下是`UserID`(不显示`UserID`作为主键是个好主意)。稍后,我们使用`DataRow`对象检查旧分数和新分数。最后,我们使用`DataTable`的“`GetChanges`”方法仅获取新`DataTable`中的更改。
`DataSet`也有一个“`GetChanges`”方法,您可以使用它来执行相同的操作。
private void Button1_Click(object sender, System.EventArgs e)
{
// Gets the DataSet from the Session
oldDataSet = (DataSet) Session["DataSet"];
// Gets the DataTable out of the DataSet
DataTable oldDataTable = oldDataSet.Tables[0];
DataTable newDataTable = new DataTable();
DataRow dataRow;
int oldScore = 0;
foreach(DataGridItem dgi in DataGrid1.Items)
{
// Gets the text out of the Score column and convert it to Int32
int score = Convert.ToInt32(((TextBox) dgi.FindControl("TextBox1")).Text);
// Get the UserID out of the first column
int userID = Convert.ToInt32(dgi.Cells[0].Text);
// Make a DataColumn object which is used to set the primary key
DataColumn[] userIDColumn = new DataColumn[1];
userIDColumn[0] = (DataColumn) oldDataTable.Columns["UserID"];
// Set the primary key to the oldDataTable
oldDataTable.PrimaryKey = userIDColumn;
dataRow = oldDataTable.Rows.Find(userID);
if(DBNull.Value == dataRow["Test1"])
{ dataRow["Test1"] = score; }
else
{
oldScore = Convert.ToInt32(dataRow["Test1"]);
// Check to see if the score has changed or not
if(score != oldScore)
{ dataRow["Test1"] = score; }
}
}
// Get only the changes from the oldDataTable to the newDataTable
newDataTable = oldDataTable.GetChanges();
// Bind the newDataTable to the DataGrid
DataGrid2.DataSource = newDataTable;
DataGrid2.DataBind();
}
结果
您可以在下面的图片中看到,我仅从`DataTable`对象中检索了我更改的字段,没有其他内容。
结论
获取已更改或修改的行,而不是将所有数据发送到数据库,总是更好。
历史
- 2008年1月19日:最初发布