6、DataAdapter的使用

    .NET框架通过 DataAdapter 来控制与现有数据源的交互,每个 .NET 数据提供程序都包含一个 DataAdapter对象;OLE DB .NET 数据提供程序包含一个 OLEDBDataAdapter 对象,

 而 SQL Server .NET 数据提供程序包含一个 SqlDataAdapter 对象。

 DataAdapter 对象用于从数据源中检索数据并填充 DataSet 中的表,并且还会将对 DataSet 作出的更改解析回数据源。

 DataAdapter 使用 .NET 数据提供程序的 Connection 来连接到数据源,使用 Command 对象从数据源中检索数据并将更改解析回数据源。

 

 6.1、使用DataAdapter填充DataSet


     DataAdapter 的 SelectCommand 属性是一个 Command 对象,它从数据源中检索数据。DataAdapter 的InsertCommand、UpdateCommand和DeleteCommand属性也是 Command 对象,

  它们按照对 DataSet 中数据的修改来管理对数据源中数据的更新。

  DataAdapter 的Fill方法用于使用 DataAdapter 的SelectCommand 的结果来填充 DataSet。Fill将要填充的DataSet和DataTable对象用作它的参数。

  如果数据源中存在主键且 DataAdapter.MissingSchemaAction设置为MissingSchemaAction.AddWithKey,否则不会创建主键。

 

  6.1.1、代码:

      SqlConnection nwindConn = new SqlConnection("……");

   SqlCommand selectCMD = new SqlCommand("SELECT CustomerID, CompanyName FROM Customer", nwindConn);

   selectCMD.CommandTimeout = 30;

   SqlDataAdapter custDA = new SqlDataAdapter();

   custDA.SelectCommand = selectCMD;

   nwindConn.Open();

   DataSet custDS = new DataSet();

   custDA.Fill(custDS, "Customers");

   nwindConn.Close();

   

   OleDbConnection nwindConn = new OleDbConnection("……");

   OleDbCommand selectCMD = new OleDbCommand("SELECT CustomerID, CompanyName FROM Customers", nwindConn);

   selectCMD.CommandTimeout = 30;

   OleDbDataAdapter custDA = new OleDbDataAdapter();

   custDA.SelectCommand = selectCMD;

   DataSet custDS = new DataSet();

   custDA.Fill(custDS, "Customers");

   //这段代码没有显示的打开和关闭 Connection 如果Fill方法发现连接尚未打开,它将隐式的打开并关闭 Connection

   

   6.1.2、多个结果集

       如果 DdataAdapter 遇到多个结果集,它将在 DataSet 中创建多个表。将向这些表提供递增的默认名称 TableN,

    以表示 Table() 的Table为第一个表名。如果以参数形式向Fill方法传递表名称,则将向这些表提供递增的默认名称 TableNameN,

    这些表名称以表示TableName() 的 TableName为起始。

   

   6.1.2、从多个 DataAdapter 填充 DataSet

       可以将任意数量的DataAdapter与一个DataSet一起使用。每个DataAdapter都可用于填充一个或多个DataTable对象并将更新解析回相关数据源。

    //下面代码示例从 Microsoft SQL Server 2000上的Northwind数据库填充客户列表,从存储在 Microsoft Access 2000 中的Northwind数据库填充订单列表。

   

    using System;

    using System.Data;

    using System.Data.SqlClient;

    using System.Data.OleDb;

   

    class DoubleAdapter

    {

     public static void Main()

     {

      SqlConnection custConn = new SqlConnection("……");

      SqlDataAdapter custDA = new SqlDataAdapter("SELECT * FROM Customers", custConn);

     

      OleDbConnection orderConn = new OleDbConnection("……");

      OleDbDataAdapter orderDA = new OleDbDataAdapter("SELECT * FROM Orders", orderConn);

     

      custConn.Open();

      orderConn.Open();

     

      DataSet custDS = new DataSet();

     

      //填充数据集

      custDA.Fill(custDS, "Customers");

      orderDA.Fill(custDS, "Orders");

     

      //关闭连接

      custConn.Close();

      orderConn.Close();

     

      DataRelation custOrderRel = custDS.Relations.Add("Customers",

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

      custDS.Tables["Orders"].Columns["OrderID"]);

     

      foreach (DataRow pRow in custDS.Tables["Customers"].Rows)

      {

       Console.WriteLine(pRow["CustomerID"]);

       foreach (DataRow cRow in pRow.GetChildRows(custOrderRel))

       {

        Console.WriteLine("\t" + cRow["OrderID"])

       }

      }

     }

    }

   

 6.2、使用DataAdapter、DataSet更新数据库

     DataAdapter 的 Update 方法可调用来将 DataSet中的更改解析回数据源。与Fill方法类似,

     Update方法将DataSet实例和可选DataTable对象或DataTable名称用作参数。

     DataSet实例是包含已作出的更改的DataSet,而D啊他Table标识从其中检索更改的表。

        当调用Update方法时,DataAdapter将分析已作出的更改并执行相应的命令(INSERT、UPDATE、DELETE)。

        当DataAdapter遇到对DataRow的更改时,它将使用InsertCommand、UpdateCommand、DeleteCommand来处理该更改。

        当不存在用于已删除行的DeleteCommand或其他命令,将引发异常。

       

        6.2.1、使用DataAdapter参数

            DataAdapter的Command参数可用于为DataSet中每个已修改行的SQL语句或存储过程指定输入和输出的值。

            在调用DataAdapter的Update方法之前,必须设置InsertCommand、UpdateCommand或DeleteCommand属性。

   //示例代码:

       custDA.Parameters.Add("@CompanyName", SqlDbType.NChar, 15, "CompanyName");

    SqlParameter myParm = custDA.UpdateCommand.Parameters.Add("@CustomerID", SqlDbType.NChar, 5, "CustomerID");

    myParm.SourceVersion = DataRowVersion.Original;

   

    Parameters集合的Add方法采用参数的名称、DataAdapter特定类型、大小(如果可应用于该类型)以及 DataTable中SourceColumn

    的名称。请注意,@CustomerID参数的SourceVersion设置为Original。这样,如果标识列的值已经在修改后的DataRow中被更改,

    就一定会更新数据源中的现有行。在这种情况下,Original行值将匹配数据源中的当前值,而Current行值将包含更新的值。

    如果没有为@CompanyName参数设置SourceVersion,而将使用默认的Current行值。


7、创建和使用DataSet

    7.1、DataSet涉及到的方法:

     在DataSet中以编程方式创建DataTables、DataRelations和Constraints并使用数据填充这些表。

  通过DataAdapter用现有关系数据源中的数据表填充DataSet。

  使用XML加载和保持DataSet内容。


 7.2、创建DataSet

     默认参数为: "NewDataSet"

  //代码:

  DataSet custDS = new DataSet("xxx");


 7.3、向DataSet添加DataTable

     ADO.NET可以创建DataTable对象并将其添加到现有的DataSet中。可以使用要添加到DataTable的Columns集合中的DataColumn对象的PromaryKey和Unique属性来设置DataTable的约束信息。

  //示例代码: 以下构造一个DataSet,将一个新的DataTabel对象添加到该DataSet中,然后将3个DataColumn对象添加到该表中,最后设置一个主键列。

  DataSet custDS = new DataSet("CustomerOrders");

  DataTable orderTable = custDS.Table.Add("Orders");

  //添加Column

  DataColumn pkCol = ordersTable.Columns.Add("OrderID", typeof(Int32));

  ordersTable.Columns.Add("OrderQuantity", typeof(Int32));

  ordersTable.Columns.Add("CompanyName", typeof(string));

  //添加主键

  orderTable.PrimaryKey = new DataColumn[]{pkCol};


 7.4、添加表关系DataRelation

     在包含多个DataTable对象的DataSet中,可以使用DataRelation对象来使一个表与另一个表相关,在多个表之间导航,

  以及从相关表中返回子行或父行。

 

  创建DataRelation所需的参数是DataRelation的名称以及用作关系中父列和子列的一个或多个DataColumn引用的数组。

  当创建DataRelation后,可以使用它在多个表之间导航和检索值。默认情况下,向DataSet中添加DataRelation会将一个

  UniqueConstraint添加到父表中,并将一个ForeignKeyConstraint添加到子表中。

 

  //一下代码示例使用DataSet中的两个DataTable对象来创建一个DataRelation。每个DataTable包含一个名为CustID的列,它用作两个DataTable对象之间的链接。

  //每个DataTable包含一个名为CustID的列,它用作两个DataTable对象之间的链接。

  //该示例中的第一个参数所创建的DataRelation的名称。第二个参数设置父DataColumn,第三个参数设置子DataColumn。

  custDS.Relations.Add("CustOrders", custDS.Tables["Customers"].Columns["CustID"]),

  custDS.Tables["Orders"].Columns["CustID"]);