使用 .NET Framework 编辑数据集中的数据

注意

数据集和相关类是 2000 年代初的旧 .NET Framework 技术,使应用程序能够在应用程序与数据库断开连接时处理内存中的数据。 它们对于使用户能够修改数据并持续更改回数据库的应用程序特别有用。 虽然数据集已被证明是一项非常成功的技术,但我们建议新的 .NET 应用程序使用 Entity Framework Core。 实体框架提供了一种更自然的方式来将表格数据作为对象模型,并且具有更简单的编程接口。

编辑数据表中的数据与编辑任何数据库中的表中的数据非常类似。 该过程可能包括插入、更新和删除表中的记录。 在数据绑定窗体中,可以指定用户可编辑的字段。 在这种情况下,数据绑定基础结构会处理所有更改跟踪,以便以后可以将更改发送回数据库。 如果以编程方式对数据进行编辑,并且打算将这些更改发送回数据库,则必须使用用于执行更改跟踪的对象和方法。

除更改实际数据之外,还可查询 DataTable 以返回特定数据行。 例如,可查询单个行、特定版本的行(原始和建议)、更改的行或具有错误的行。

编辑数据集中的行

若要编辑 DataTable 中的现有行,需要找到要编辑的 DataRow,然后将更新的值分配给所需的列。

如果不知道要编辑的行的索引,请使用 FindBy 方法按主键进行搜索:

NorthwindDataSet.CustomersRow customersRow = 
    northwindDataSet1.Customers.FindByCustomerID("ALFKI");

customersRow.CompanyName = "Updated Company Name";
customersRow.City = "Seattle";

如果知道行索引,可按如下所示访问和编辑行:

northwindDataSet1.Customers[4].CompanyName = "Updated Company Name";
northwindDataSet1.Customers[4].City = "Seattle";

将新行插入数据集

使用数据绑定控件的应用程序通常通过 BindingNavigator 控件上的“添加新项”按钮来添加新记录。

若要将新记录手动添加到数据集,请通过调用 DataTable 上的方法创建新的数据行。 然后,将该行添加到 DataTableDataRow 集合 (Rows):

NorthwindDataSet.CustomersRow newCustomersRow = 
    northwindDataSet1.Customers.NewCustomersRow();

newCustomersRow.CustomerID = "ALFKI";
newCustomersRow.CompanyName = "Alfreds Futterkiste";

northwindDataSet1.Customers.Rows.Add(newCustomersRow);

若要保留数据集向数据源发送更新所需的信息,请使用 Delete 方法删除数据表中的行。 例如,如果应用程序使用 TableAdapter(或 DataAdapter),则 TableAdapter 的 Update 方法会删除数据库中具有 DeletedRowState 的行。

如果应用程序不需要将更新发送回数据源,则可通过直接访问数据行集合 (Remove) 来删除记录。

删除记录集中的记录

  • 调用 DataRowDelete 方法。

    此方法不会以物理方式删除记录。 而是标记要删除的记录。

    注意

    如果获取 DataRowCollection 的 count 属性,则生成的计数包括已标记为要删除的记录。 若要获取未标记为要删除的记录的准确计数,可以循环访问集合,查看每条记录的 RowState 属性。 (标记为删除的记录具有 DeletedRowState。)或者,可以创建数据集的数据视图,该数据集基于行状态进行筛选,然后从该视图获取 count 属性。

以下示例演示如何调用 Delete 方法,以将 Customers 表中的第一行标记为已删除:

northwindDataSet1.Customers.Rows[0].Delete();

确定是否有更改的行

对数据集中的记录进行更改时,将存储有关这些更改的信息,直到提交这些更改。 在调用数据集或数据表的 AcceptChanges 方法时,或在调用 TableAdapter 或数据适配器的 Update 方法时提交更改。

在每个数据行中,通过以下两种方式跟踪更改:

  • 每个数据行都包含与其 RowState 相关的信息(例如 AddedModifiedDeletedUnchanged)。

  • 每个更改后的数据行都包含该行 (DataRowVersion) 的多个版本、原始版本(更改之前)和当前版本(更改之后)。 在更改挂起期间(可以响应 RowChanging 事件的时候),第三个版本(建议的版本)也可用。

如果在数据集中进行了更改,则数据集的 HasChanges 方法将返回 true。 确定已更改的行存在后,可调用 DataSetDataTableGetChanges 方法来返回一组已更改的行。

确定是否对任意行进行了更改

  • 调用数据集的 HasChanges 方法以检查是否有更改的行。

以下示例演示如何检查 HasChanges 方法的返回值,以检测名为 NorthwindDataset1 的数据集中是否有更改的行:

if (northwindDataSet1.HasChanges()) 
{
    // Changed rows were detected, add appropriate code.
}
else
{
    // No changed rows were detected, add appropriate code.
}

确定更改的类型

还可检查数据集中进行了哪些类型的更改,方法是将 DataRowState 枚举中的值传递给 HasChanges 方法。

确定对行进行了哪些类型的更改

以下示例演示如何检查名为 NorthwindDataset1 的数据集,以确定是否向该数据集添加了任何新行:

if (northwindDataSet1.HasChanges(DataRowState.Added)) 
{
    // New rows have been added to the dataset, add appropriate code.
}
else
{
    // No new rows have been added to the dataset, add appropriate code.
}

查找出错的行

使用单个列和数据行时,可能会遇到错误。 可检查 HasErrors 属性来确定 DataSetDataTableDataRow 中是否存在错误。

  1. 检查 HasErrors 属性,查看数据集中是否有错误。

  2. 如果 HasErrors 属性为 true,则循环访问表的集合,然后通过行来查找出现错误的行。

private void FindErrors() 
{
    if (dataSet1.HasErrors)
    {
        foreach (DataTable table in dataSet1.Tables)
        {
            if (table.HasErrors)
            {
                foreach (DataRow row in table.Rows)
                {
                    if (row.HasErrors)
                    {
                        // Process error here.
                    }
                }
            }
        }
    }
}