随笔 - 6  文章 - 129  trackbacks - 0
<2024年12月>
24252627282930
1234567
891011121314
15161718192021
22232425262728
2930311234

常用链接

留言簿(14)

随笔档案(6)

文章分类(467)

文章档案(423)

相册

收藏夹(18)

JAVA

搜索

  •  

积分与排名

  • 积分 - 822288
  • 排名 - 49

最新评论

阅读排行榜

评论排行榜

转自:http://blog.csdn.net/cui55/article/details/1371411

 DataSet 中创建 DataTable 之后,您执行的活动可以与使用数据库中的表时执行的活动相同。您可以添加、查看、编辑和删除表中的数据;可以监视错误和事件;并且可以查询表中的数据。在修改 DataTable 中的数据时,您也可以验证更改是否正确,并决定是否以编程方式接受更改或拒绝更改。

本节内容

将数据添至表中:说明如何创建新行并将其添至表中。

在创建 DataTable 并使用列和约束定义其结构之后,您可以将新的数据行添至表中。要添加新行,可将一个新变量声明为 DataRow 类型。调用 NewRow 方法时,将返回新的 DataRow 对象。然后,DataTable 会根据表的结构按 DataColumnCollection 的定义创建 DataRow 对象。

以下示例演示了如何通过调用 NewRow 方法来创建新行。

DataRow workRow = workTable.NewRow();

然后您可以使用索引或列名来操作新添加的行,如下例所示。

workRow["CustLName"] = "Smith";
workRow[1] = "Smith";

在将数据插入新行后,Add 方法可用于将行添至 DataRowCollection,如以下代码所示。

workTable.Rows.Add(workRow);

您也可以通过传入值的数组(类型化为 Object),调用 Add 方法来添加新行,如下例所示。

workTable.Rows.Add(new Object[] {1, "Smith"});

将类型化为 Object 的值的数组传递到 Add 方法,可在表内创建新行并将其列值设置为对象数组中的值。请注意,数组中的值会根据它们在表中出现的顺序相继与各列匹配。

以下示例将十行添至新建的 Customers 表中。

DataRow workRow;

for (int i = 0; i <= 9; i++) 
{
  workRow = workTable.NewRow();
  workRow[0] = i;
  workRow[1] = "CustName" + i.ToString();
  workTable.Rows.Add(workRow);
}

查看表中数据:说明如何访问行中的数据,包括数据的原始版本和当前版本。

可以使用 DataTable  Rows  Columns 集合来访问 DataTable 中的内容。也可以根据包括搜索标准、排序顺序和行状态等特定标准,使用 DataTable.Select 方法返回 DataTable 中数据的子集。此外,用主键值搜索特定行时,还可使用 DataRowCollection  Find 方法。

DataTable 对象的 Select 方法返回一组与指定条件匹配的 DataRow 对象。Select 采用筛选表达式、排序表达式和 DataViewRowState 的可选参数。筛选表达式根据 DataColumn 值(例如 LastName = 'Smith'。排序表达式遵循用于为列排序的标准 SQL 约定,例如 LastName ASC, FirstName ASC。有关编写表达式的规则,请参阅DataColumn 类的 Expression 属性。

提示 如果您将对 DataTable  Select 方法执行多次调用,可通过先为 DataTable 创建 DataView来提高性能。创建 DataView 会为表中的行编制索引。然后,Select 方法会使用该索引,这样将显著缩短生成查询结果的时间。有关为 DataTable 创建 DataView 的信息,请参阅创建和使用 DataView

Select 方法基于 DataViewRowState 确定要查看或操作的行的版本。下表说明了可能的 DataViewRowState 枚举值。

成员名称 说明
CurrentRows 当前行,包括未更改的行、已添加的行和已修改的行。
Deleted 已删除的行。
ModifiedCurrent 当前版本,它是原始数据的修改版本(请参阅ModifiedOriginal)。
ModifiedOriginal 所有已修改行的原始版本。使用 ModifiedCurrent 时,当前版本可用。
Added 新行。
None 无。
OriginalRows 原始行,包括未更改的行和已删除的行。
Unchanged 未更改的行。

在下面的示例中,DataSet 对象已经过筛选,这样,您可以只使用其 DataViewRowState 设置为 CurrentRows的行。

DataRow[] currRows = workTable.Select(null, null, DataViewRowState.CurrentRows);

if (currRows.Length < 1 )
  Console.WriteLine("No Current Rows Found");
else
{
  foreach (DataColumn myCol in workTable.Columns)
    Console.Write("/t{0}", myCol.ColumnName);

  Console.WriteLine("/tRowState");

  foreach (DataRow myRow in currRows)
  {
    foreach (DataColumn myCol in workTable.Columns)
      Console.Write("/t{0}", myRow[myCol]);

    Console.WriteLine("/t" + myRow.RowState);
  }
}

Select 方法可用于返回具有不同 RowState 值或字段值的行。以下示例返回一个引用所有已删除行的 DataRow数组,并返回另一个引用所有已排序行(按照 CustLName 排序,其中 CustID 列大于 5)的 DataRow 数组。

// Retrieve all deleted rows.
DataRow[] delRows = workTable.Select(null, null, DataViewRowState.Deleted);

// Retrieve rows where CustID > 5, and order by CustLName.
DataRow[] custRows = workTable.Select("CustID > 5", "CustLName ASC");

编辑表中的数据:说明如何修改行中的数据,包括挂起对行的更改,直至验证并接受了建议的更改。

当您在 DataRow 中更改列值时,所做更改会立即置于行的 Current 状态中。然后,RowState 会设置为Modified,并使用 DataRow  AcceptChanges  RejectChanges 方法来接受或拒绝所做更改。DataRow还提供了三种可用于在编辑行时将行的状态挂起的方法。这些方法是 BeginEditEndEdit  CancelEdit

当您直接在 DataRow 中修改列值时,DataRow 会使用 CurrentDefault  Original 行版本来管理列值。除这些行版本以外,BeginEditEndEdit  CancelEdit 方法还使用第四个行版本:Proposed

在执行编辑操作(通过调用 BeginEdit 开始,并且通过使用 EndEdit  CancelEdit 或者通过调用AcceptChanges  RejectChanges 结束)的过程中,Proposed 行版本会存在。

在编辑操作过程中,您可以通过计算 DataTable  ColumnChanged 事件中的 ProposedValue 来将验证逻辑应用于各列。ColumnChanged 事件保存 DataColumnChangeEventArgs,可保持对正在更改的列和ProposedValue 的引用。计算了建议值后,可以对其进行修改或取消编辑。编辑结束时,行从 Proposed 状态中移出。

您可以通过调用 EndEdit 来确认编辑,也可以通过调用 CancelEdit 来取消编辑。请注意,尽管 EndEdit 确实已确认您所做的编辑,但在调用 AcceptChanges 之前,DataSet 并没有实际接受更改。另外请注意,如果在EndEdit  CancelEdit 编辑结束之前调用 AcceptChanges,编辑将会终止,并接受 Current  Original 行版本的 Proposed 行值。调用 RejectChanges 会以同样的方式结束编辑,并放弃 Current  Proposed 行版本。在调用 AcceptChanges  RejectChanges 之后调用 EndEdit  CancelEdit 不会起作用,因为编辑已经结束。

以下示例演示了如何将 BeginEdit  EndEdit  CancelEdit 一起使用。本示例也会检查 ColumnChanged 事件中的 ProposedValue,并决定是否取消编辑。

DataTable  workTable  = new DataTable();
workTable.Columns.Add("LastName", typeof(String));

workTable.ColumnChanged += new DataColumnChangeEventHandler(OnColumnChanged);

DataRow workRow = workTable.NewRow();
workRow[0] = "Smith";
workTable.Rows.Add(workRow);

workRow.BeginEdit();
// Causes the ColumnChanged event to write a message and cancel the edit.
workRow[0] = "";     
workRow.EndEdit();

// Displays "Smith, New".
Console.WriteLine("{0}, {1}", workRow[0], workRow.RowState);  


protected static void OnColumnChanged(Object sender, DataColumnChangeEventArgs args)
{
  if (args.Column.ColumnName == "LastName")
    if (args.ProposedValue.ToString() == "")
    {
      Console.WriteLine("Last Name cannot be blank. Edit canceled.");
      args.Row.CancelEdit();
    }
}

行状态与行版本:提供有关行的不同状态的信息。

ADO.NET 用行状态和版本管理表中的行。行状态表示行的状态。当修改行时,行版本会维护存储于行中的值,包括当前值、原始值和默认值。例如,修改了某行中的一列后,该行会有一个 Modified 的行状态,并且会存在两个行版本:Current(包含当前行值)和 Original(包含修改该列前的行值)。

每个 DataRow 对象都具有 RowState 属性,您可以检查此属性来确定行的当前状态。下表给出了对各RowState 枚举值的简要说明。

RowState 说明
Unchanged 自上次调用 AcceptChanges 之后,或自 DataAdapter.Fill 创建了行之后,未做出过任何更改。
Added 已将行添至表中,但尚未调用 AcceptChanges
Modified 已更改了行的一些元素。
Deleted 已将该行从表中删除,并且尚未调用 AcceptChanges
Detached 对于已经创建但不属于任何 DataRowCollection 的行,设置为 Detached。新建行的 RowState设置为 Detached。通过调用 Add 方法将新的 DataRow 添至 DataRowCollection 之后,RowState 属性的值设置为 Added

对于已经使用 Remove 方法(或是在使用 Delete 方法之后使用了 AcceptChanges 方法)从DataRowCollection 中移除的行,也设置为 Detached

 DataSetDataTable  DataRow 上调用 AcceptChanges 时,会移除行状态为 Deleted 的所有行。剩余的行会被赋予 Unchanged 行状态,并且 Original 行版本中的值会改写为 Current 行版本值。调用RejectChanges 时,会移除行状态为 Added 的所有行。剩余的行会被赋予 Unchanged 的行状态,并且Current 行版本中的值会改写为 Original 行版本值。

通过用列引用来传递 DataRowVersion 参数,您可以查看行的不同行版本,如下例所示。

DataRow custRow = custTable.Rows[0];
string custID = custRow["CustomerID", DataRowVersion.Original].ToString();

下表给出了各 DataRowVersion 枚举值的简要说明。

DataRowVersion 说明
Current 行的当前值。如果是有 Deleted  RowState 的行,则不存在此行版本。
Default 特定行的默认行版本。AddedModified  Unchanged 行的默认行版本是CurrentDeleted 行的默认行版本是 OriginalDetached 行的默认行版本是 Proposed
Original 行的原始值。如果是有 Added  RowState 的行,则不存在此行版本。
Proposed 行的建议值。在对行进行编辑操作期间,或对于不属于 DataRowCollection 的行,存在此行版本。

通过调用 HasVersion 方法并将 DataRowVersion 作为参数传递,您可以测试 DataRow 是否具有特定的行版本。例如,在调用 AcceptChanges 之前,DataRow.HasVersion(DataRowVersion.Original) 对新添加的行将返回 false

例如,以下代码示例显示了表中所有已删除行的值。已删除的行没有 Current 行版本,因此在访问列值时必须传递 DataRowVersion.Original

DataTable catTable = catDS.Tables["Categories"];

DataRow[] delRows = catTable.Select(null, null, DataViewRowState.Deleted);

Console.WriteLine("Deleted rows:/n");

foreach (DataColumn catCol in catTable.Columns)
  Console.Write(catCol.ColumnName + "/t");
Console.WriteLine();

foreach (DataRow delRow in delRows)
{
  foreach (DataColumn catCol in catTable.Columns)
    Console.Write(delRow[catCol, DataRowVersion.Original] + "/t");
  Console.WriteLine();
}

从表中删除行:说明如何从表中移除行。

用于从 DataTable 对象中删除 DataRow 对象的方法有两种:DataRowCollection 对象的 Remove 方法和DataRow 对象的 Delete 方法。Remove 方法从 DataRowCollection 中删除 DataRow,而 Delete 方法只将行标记为删除。当应用程序调用 AcceptChanges 方法时,才会发生实际的删除。通过使用 Delete,您可以在实际删除之前先以编程方式检查哪些行标记为删除。如果将行标记为删除,其 RowState 属性会设置为 Deleted

在将 DataSet  DataTable  DataAdapter 和关系型数据源一起使用时,用 DataRow  Delete 方法移除行。Delete 方法只是在 DataSet  DataTable 中将行标记为 Deleted,而不会移除它。而 DataAdapter 在遇到标记为 Deleted 的行时,会执行其 DeleteCommand 以在数据源中删除该行。然后,就可以用AcceptChanges 方法永久移除该行。如果使用 Remove 删除该行,则该行将从表中完全移除,但DataAdapter 不会在数据源中删除该行。

DataRowCollection  Remove 方法采用 DataRow 作为参数,并将其从集合中移除,如下例所示。

workTable.Rows.Remove(workRow);

作为对比,以下示例演示了如何调用 DataRow 上的 Delete 方法来将其 RowState 改为 Deleted

workRow.Delete();

如果将行标记为删除,并且调用 DataTable 对象的 AcceptChanges 方法,该行就会从 DataTable 中移除。相比之下,如果调用 RejectChanges,行的 RowState 就会恢复到被标记为 Deleted 之前的状态。

注意 如果 DataRow  RowState  Added,则意味着已将其添至表中,然后将其标记为Deleted,从表中移除。

添加和读取行错误信息:说明如何按行插入错误信息,以用于解决有关应用程序内行中数据的问题。

为了避免在编辑 DataTable 中的值时每次发生行错误都必须响应,可将错误信息添至行中,以便以后使用。DataRow 对象通过对各行提供 RowError 属性来支持此功能。将数据添至 DataRow  RowError 属性会将DataRow  HasErrors 属性标记为 true。如果 DataRow  DataTable 的组成部分,且 DataRow.HasErrors true,则 DataTable.HasErrors 属性也是 true。这也适用于 DataTable 所属的 DataSet。为错误做测试时,可以检查 HasErrors 属性以确定错误信息是否已添至所有行。如果 HasErrors  true,则可使用 DataTable GetErrors 方法以便只返回和检查有错误的行,如下例所示。

DataTable  workTable = new DataTable("Customers");
workTable.Columns.Add("CustID", typeof(Int32));
workTable.Columns.Add("Total", typeof(Double));

workTable.RowChanged += new DataRowChangeEventHandler(OnRowChanged);

for (int i = 0; i < 10; i++)
  workTable.Rows.Add(new Object[] {i, i*100});

if (workTable.HasErrors)
{
  Console.WriteLine("Errors In Table " + workTable.TableName);

  foreach (DataRow myRow in workTable.GetErrors())
  {
    Console.WriteLine("CustID = " + myRow["CustID"]);
    Console.WriteLine(" Error = " + myRow.RowError + "/n");
  }
}

protected static void OnRowChanged(Object sender, DataRowChangeEventArgs args)
{
  // Check for zero values.
  if (args.Row["Total"].Equals(0D))
    args.Row.RowError = "Total cannot be 0.";
}

接受或拒绝对行的更改:说明如何接受或拒绝对行的更改。

在检验过对 DataTable 中的数据所做更改的准确性之后,可使用 DataRowDataTable  DataSet AcceptChanges 方法来接受更改,此方法会将 Current 行值设置为 Original 值,并会将 RowState 属性设置为 Unchanged。接受或拒绝更改会清除所有 RowError 信息,并将 HasErrors 属性设置为 false。接受或拒绝更改还可以影响在数据源中更新数据。有关更多信息,请参阅使用 DataAdapter 和 DataSet 更新数据库

如果 DataTable 上存在外键约束,使用 AcceptChanges  RejectChanges 接受或拒绝的更改就会根据ForeignKeyConstraint.AcceptRejectRule 传播至 DataRow 的子行。

以下示例检查有错误的行,在适用之处解决错误,拒绝无法解决错误的行。请注意,对于解决的错误,RowError值会重置为空字符串,导致将 HasErrors 属性设置为 false。当解决或拒绝了所有的有错误的行时,就会调用AcceptChanges 来接受对整个 DataTable 的所有更改。

if (workTable.HasErrors)
{

  foreach (DataRow errRow in workTable.GetErrors())
  {
    if (errRow.RowError == "Total cannot exceed 1000.")
    {
      errRow["Total"] = 1000;
      errRow.RowError = "";    // Clear the error.
    }
    else
      errRow.RejectChanges();
  }
}

workTable.AcceptChanges();

处理 DataTable 事件:提供可用于 DataTable 的事件的相关信息,包括修改列值和添加或删除行时的事件。

DataTable 对象提供一系列可由应用程序处理的事件。下表说明了 DataTable 事件。
事件 说明
ColumnChanged 在值已成功插入列时发生。
ColumnChanging 在已提交列值时发生。
RowChanged 在已成功编辑表中的行后发生。
RowChanging 当正在更改表中的行时发生。
RowDeleted 在表中的某行已被标记为 Deleted 之后发生。
RowDeleting 在表中的某行被标记为 Deleted 之前发生。

以下示例创建 4 个事件:OnColumnChangedOnColumnChangingOnRowChanged OnRowChanging。这些事件中的每一个都在列或行更改时发生。

workTable.ColumnChanged  += new DataColumnChangeEventHandler(OnColumnChanged);
workTable.ColumnChanging += new DataColumnChangeEventHandler(OnColumnChanging);
workTable.RowChanged     += new DataRowChangeEventHandler(OnRowChanged);
workTable.RowChanging    += new DataRowChangeEventHandler(OnRowChanging);

protected static void OnColumnChanged(object sender, DataColumnChangeEventArgs args)
{
  Console.Write(" ColumnChanged: ");
  Console.Write(args.Column.ColumnName + " changed to '" + args.ProposedValue + "'/n");
}

protected static void OnColumnChanging(object sender, DataColumnChangeEventArgs args)
{
  Console.Write("ColumnChanging: ");
  Console.Write(args.Column.ColumnName + " equals '" + args.Row[args.Column] + 
                    "', changing to '" + args.ProposedValue + "'/n");    
}

protected static void OnRowChanging(object sender, DataRowChangeEventArgs args)
{
  if (args.Action != DataRowAction.Nothing)
    Console.WriteLine("   RowChanging: Action = " + args.Action + ", CustID = " + args.Row["CustID"]);
}

protected static void OnRowChanged(object sender, DataRowChangeEventArgs args)
{
  if (args.Action != DataRowAction.Nothing)
    Console.WriteLine("    RowChanged: Action = " + args.Action + ", CustID = " + args.Row["CustID"]);
}



posted on 2014-06-30 11:08 Ke 阅读(2604) 评论(0)  编辑  收藏 所属分类: C#

只有注册用户登录后才能发表评论。


网站导航: