8、DataTable创建数据表

    DataTable表示一个内存内关系数据的表,可以独立创建和使用,也可以由其他.NET框架对象使用,

 最常见的情况是作为DataSet的成员使用。

 DataTable对象可通过使用DataTable构造函数来创建,或者可通过将构造函数参数传递到DataSet

 的Tables属性的Add方法来创建。

 DataTable对象可通过使用DataAdapter对象的Fill方法或FillSchema方法在DataSet内创建,或者可使用

 DataSet的ReadXml、ReadXmlSchema或InferXmlSchema方法从预定义的或推断的XML架构中创建。

 将DataTable添加为一个DataSet的Tables集合的成员后,不能再将其添加至任何其他DataSet的表的集合。

 //以下代码创建DataTable对象的实例,并为其指定名称"Customers"

 DataTable workTable = new DataTable("Customers");

 

 //以下代码创建DataTable实例,方法是:将其添加至DataSet的Tables集合

 DataSet custDS = new DataSet();

 DataTable custTable = custDS.Tables.Add("CustTable");

 

 

 8.1、定义数据表的架构

     表的架构或结构由列和约束表示,使用DataColumn对象以及ForeignKeyConstraint和UniqueConstraint

  对象定义DataTable的架构。表中的列可以映射到数据源中的列、包含从表达式计算所得的值、自动递增

  它们的值,或包含主键值。

      8.1.1、在表中添加列

       DataTable包含了由表的Columns属性引起的DataColumn对象的集合。这个列的集合与任何约束一起

    定义表的架构或结构。

    通过使用DataColumn构造函数,或者通过调用表的Columns属性的Add方法可以在表内创建DataColumn

    对象。Add方法将接受可选的ColumnName、DataType和Expression参数,并将创建新的DataColumn

    作为集合的成员。

   

    //以下代码将4行添加到DataTable

    DataTable workTable = new DataTable("Customers");

    DataColumn workCol = workTable.Columns.Add("CustID", typeof(Int32));

    workCol.AllowDBNull = false;

    workCol.Unique = true;

    workTable.Columns.Add("CustLName", typeof(String));

    workTable.Columns.Add("CustFName", typeof(String));

    workTable.Columns.Add("Purchases", typeof(Double));

   

    如果尚为给某个列提供列名,则将该列添加至DataColumnCollection时,该列会得到从"Columns"开始

    递增的默认名称ColumnN。

   8.1.2、创建表达式列

       可以为列定义表达式,让它能够包含同一行中其它列值或表中多行的列值计算而得的值。

    //实例代码

    workTable.Columns.Add("Total", typeof(Double));

    workTable.Columns.Add("SalesTax", typeof(Double), "Total * 0.086");

    表达式可以引用其他表达式列,但循环引用(其中两个表达式相互引用)将产生异常。

   

   8.1.3、创建Autoincrement列

       要确保列中的值唯一,可将列值设置为在表中添加新行时自动递增。

    //以下代码创建从200开始并以3为增量进行添加的列

    DataColumn workColumn = workTable.Columns.Add("CustomerID", typeof(Int32));

    workColumn.AutoIncrement = true;

    workColumn.AutoIncrementSeed = 200;

    workColumn.AutoIncrementStep = 3;

   

   8.1.4、定义主键

       在将一个单独的DataColumn标识为DataTable的PrimaryKey时,表会自动将列的AllowDBNull属性

    设置为false,并将Unique属性设置为true。如果是多列主键,则只有AllowDBNull属性自动设置为false。

    //示例代码

    workTable.PrimaryKey = new DataColumn[]{workTable.Columns["CustID"]};

    //或采用以下代码

    DataColumn[] myColArray = new DataColumn[1];

    myColArray[0] = workTable.Columns["CustID"];

    workTable.PrimaryKey = myColArray;

   

    //下面示例将两列定义为主键

    workTable.PrimaryKey = new DataColumn[]{workTable.Columns["CustLName"],

                               workTable.Columns["CustFName"]};

         

    //或者采用以下代码

    DataColumn[] myKey = new DataColumn[2];

    myKey[0] = workTable.Columns["CustLName"];

    myKey[1] = workTable.Columns["CustFName"];

    workTable.PrimaryKey = myKey;

   

      8.1.5、添加约束

       ADO.NET中有两种约束: ForeignKeyConstraint和UniqueConstraint。默认情况下,通

    过将DataRelation添加至DataSet来创建两个或多个表之间的关系时,两种约束会自动创建。

    但是也可以在创建关系时,通过指定createConstraints = false 禁用这一行为。

   

    //外键

    ForeignKeyConstraint可以限制并传播对相关列的更改。根据列的ForeignKeyConstraint属性,

    并且如果DataSet的EnforceConstraints属性是 true ,对父行执行某些特定操作将会导致异常。

    例如:如果ForeignKeyConstraint的DeleteRule属性是None,那么在父行有子行的情况下,则无法删除父行。

   

    //示例代码

    ForeignKeyConstraint custOrderFK = new ForeignKeyConstraint("CustOrderFK");

    custDS.Tables["CustTable"].Columns["CustomerID"],

    custDS.Tables["OrdersTable"].Columns["CustomerID"]);

    custOrderFK.DeleteRule = Rule.None;

   

    //不能删除具有订单的顾客

    custDS.Tables["OrdersTable"].Constraints.Add(custOrderFK);

   

    //唯一键

    //以下代码为DataTable的两列创建UniqueConstraint

    DataTable custTable = custDS.Tables["Customers"];

    UniqueConstraint custUC = new UniqueConstraint(

    new DataColumn[]{custTable.Columns["CustomerID"], custTable.Columns["CompanyName"]});

    custDS.Tables["Customers"].Constraints.Add(custUC);

   

9、在数据表中操作数据

    9.1、将数据添至表中

     添加新行可以声明一个DataRow类型的变量。调用NewRow方法,将返回新的DataRow对象。然后DataTable

  会根据表的结构按DataColumnCollection的定义创建DataRow对象。

  //示例代码

  DataRow workRow = workTable.NewRow();

  workRow["CustLName"] = "Smith";

  workRow[1] = "Smith";

  workTable.Rows.Add(workRow);

 

  //也可以通过传入值得数组,调用Add方法来添加新行

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

  注意: 将类型化为Object值得数组传递到Add方法,可在表内创建新行并将其列值设置为对象数组中的值,

  数组中的值会根据它们在表中出现的顺序相继与各行匹配。

  //以下示例将10行添加至新建的Customers表中

  DataRow workRow;

  for (int i = 0; i < 10; i++)

  {

   workRow = workTable.NewRow();

   workRow[0] = i;

   workRow[1] = "CustName" + i.ToString();

   workTable.Rows.Add(workRow);

  }

 

 9.2、查看表中数据

         可以使用DataTable的Rows和Columns集合来访问DataTable中的内容。也可以根据包括搜索标准、排序顺序

  和行状态等特定标准,使用DataTable.Select方法返回DataTable中数据的子集。此外,用主键值搜索特定

  行时,还可使用DataRowCollection的Find方法。

      DataTable对象的Select方法返回一组与指定条件匹配的DataRow对象。Select采用筛选表达式、

  排序表达式和DataViewRowState的可选参数。筛选表达式根据DataColumn值(例如 LastName = 'Smith'),

  排序表达式遵循用于为列排序的标准SQL约定,例如LastName ASC, FirstName ASC。

      如果对DataTable的Select方法执行多次调用,可先为DataTable创建DataView来提高性能。创建DataView

  会为表中的行编制索引。然后,Select方法会使用该索引,这样将显著缩短生成查询结果的时间。