本文向您分步展示了如何获取包含数据(从数据库加载)的 DataSet、如何修改此数据,以及如何再将其发回数据库以更新原始数据源。

DataSet 对象是 Microsoft .NET Framework 中数据访问的关键部分,是可保存表、视图和关系的内存中对象。

要求

下表列出了推荐使用的硬件、软件、网络基础结构以及所需的 Service Pack:
  • Microsoft Windows Server 2003、Microsoft Windows 2000 Professional、Microsoft Windows 2000 Server、Microsoft Windows 2000 Advanced Server 或 Microsoft Windows NT 4.0 Server
  • Microsoft SQL Server 7.0 版、Microsoft SQL Server 2000 或安装了 PUBS 示例数据库的 Microsoft 数据引擎 (MSDE)
  • Microsoft Visual Studio 2005 或 Microsoft Visual Studio .NET
本文假定您熟悉下列主题:
  • 数据库术语
  • 结构化查询语言 (SQL)

如何通过 DataSet 对象更新数据库

本节演示如何使用 DataSet 对象更新数据库中的数据。还可以使用 SqlCommand 对象直接在数据库中插入、更新和删除数据,记住这一点很重要。

如想更好地理解本文,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
314145 (http://support.microsoft.com/kb/314145/ ) 如何使用 Visual C# .NET 从数据库填充 DataSet 对象
在文章 314145 (http://support.microsoft.com/kb/314145/ ) 中讲述的一些主题包括:如何从数据库中检索数据并将其传送到 DataSet 中,DataSet 如何独立于数据库以及与数据库的区别。

加载 DataSet 后,就可以修改数据了。DataSet 将会跟踪这些更改。可将 DataSet 对象视为从数据库检索出并缓存于内存中的数据。DataSet 对象由一个包含表、关系和约束的集合构成。

要更新 DataSet 并将这些更新发回数据库,请按照下列步骤操作:
  1. 启动 Visual Studio 2005 或 Visual Studio .NET。
  2. 在 Visual C# 中创建一个新的控制台应用程序。默认情况下,Visual Studio 创建一个"静态类"和一个空的 Main() 过程。
  3. 确保项目包括一个对 SystemSystem.Data 命名空间的引用。在 SystemSystem.DataSystem.Data.SqlClient 命名空间上使用 using 语句,这样,在后面的代码中就不需要从这些命名空间中限定声明。必须在任何其他声明之前使用这些语句。
    using System;
    using System.Data;
    using System.Data.SqlClient;
                                            
    
  4. 在修改数据并将更改发回数据库之前,必须将该信息加载到 DataSet 中。有关详细过程,请参见: 314145 (http://support.microsoft.com/kb/314145/ ) 。为避免重复,将不详细提供该步骤中的代码。

    以下代码中的连接字符串指向位于本地计算机(或正在运行代码的计算机)的 SQL Server。概括来说,先创建一个连接,然后创建一个数据适配器用以将数据填充到 DataSet 中。
    注意:在运行此代码之前,必须将 User ID <username> 和 Password <strong password> 更改为正确的值。请确保该用户 ID 具有在数据库中执行此操作所需的适当权限。
    string sConnectionString;
    
    // Modify the following string to correctly connect to your SQL Server.
    sConnectionString = "Password=<strong password>;User ID=<username>;"
            + "Initial Catalog=pubs;"
            + "Data Source=(local)";
    
    SqlConnection objConn
            = new SqlConnection(sConnectionString);
    objConn.Open();
    
    // Create an instance of a DataAdapter.
    SqlDataAdapter daAuthors 
            = new SqlDataAdapter("Select * From Authors", objConn);
    
    // Create an instance of a DataSet, and retrieve data from the Authors table.
    DataSet dsPubs = new DataSet("Pubs");
    daAuthors.FillSchema(dsPubs,SchemaType.Source, "Authors");
    daAuthors.Fill(dsPubs,"Authors");
                                            
    
  5. 现在已经加载了数据,您可以对其进行修改。添加行(或记录)有多种方法。该代码示例使用一个三步式过程:
    • DataTable 获取新的 DataRow 对象。
    • 根据需要设置 DataRow 字段值。
    • 将新的对象传递给 DataTable.Rows 集合的 Add 方法。
    将以下代码粘贴到步骤 4 中的代码的后面:
    //****************
    // BEGIN ADD CODE 
    // Create a new instance of a DataTable.
    DataTable tblAuthors;
    tblAuthors = dsPubs.Tables["Authors"];
    
    DataRow drCurrent;
    // Obtain a new DataRow object from the DataTable.
    drCurrent = tblAuthors.NewRow();
    
    // Set the DataRow field values as necessary.
    drCurrent["au_id"] = "993-21-3427";
    drCurrent["au_fname"] = "George";
    drCurrent["au_lname"] = "Johnson";
    drCurrent["phone"] = "800 226-0752";
    drCurrent["address"] = "1956 Arlington Pl.";
    drCurrent["city"] = "Winnipeg";
    drCurrent["state"] = "MB";
    drCurrent["contract"] = 1;
    
    // Pass that new object into the Add method of the DataTable.
    tblAuthors.Rows.Add(drCurrent);
    Console.WriteLine("Add was successful, Click any key to continue!!");
    Console.ReadLine();
    
    // END ADD CODE  
                                            
    
  6. 要编辑现有行,请获取相应的 DataRow 对象,然后为一列或多列提供新值。必须先找到正确的行,由于您加载了表的架构和数据(在步骤 4 中对 FillSchema 的调用),因此这一过程非常简单。有了架构,表就知道哪个列是它的主键,同时 Rows 集合的 Find 方法也就可用了。

    Find 方法返回 DataRow 对象,并且其主键中有了一个具体的值(在本例中为 au_id)。在有了 DataRow 之后,可对列进行修改。您不必包装 BeginEditEndEdit 中的修改,但包装可简化 DataSet 必须完成的工作,并让 DataSet 可以在调用 EndEdit 的同时执行其验证检查。将以下代码粘贴到 ADD 代码之后:
    //*****************
    // BEGIN EDIT CODE 
    
    drCurrent = tblAuthors.Rows.Find("213-46-8915");
    drCurrent.BeginEdit();
    drCurrent["phone"] = "342" + drCurrent["phone"].ToString().Substring(3);
    drCurrent.EndEdit();
    Console.WriteLine("Record edited successfully, Click any key to continue!!");
    Console.ReadLine();
    
    // END EDIT CODE  
                                            
    
  7. 要用所有这些更改来更新原始数据库,可将 DataSet 传递到 DataAdapter 对象的 Update 方法。

    不过,在调用 Update 之前,必须先设置 DataAdapter 对象的 InsertCommandUpdateCommandDeleteCommand 属性。可手动编写 SQL 并用相应的 SqlCommand 对象填充这三个属性,但也可以使用 Visual Studio .NET 自动生成这三个命令。

    要在需要时生成所需的命令,必须创建 SqlCommandBuilder 对象的实例并使用该构造函数中的 DataAdapter。如果想使用此方法(在以下代码示例中阐释),您的表必须有主键信息。要访问主键信息,可调用 FillSchema,然后将 DataAdapterMissingSchemaAction 属性设置为 AddWithKey,或在代码中手动设置主键。将以下代码粘贴到 EDIT 代码之后:
    //*****************
    // BEGIN SEND CHANGES TO SQL SERVER 
    
    SqlCommandBuilder objCommandBuilder = new SqlCommandBuilder(daAuthors);
    daAuthors.Update(dsPubs, "Authors");
    Console.WriteLine("SQL Server updated successfully, Check Server explorer to see changes");
    Console.ReadLine();
    
    // END SEND CHANGES TO SQL SERVER
                                            
    
  8. 要完全删除一行,可使用 DataRow 对象的 Delete 方法。请注意,Rows 集合包含 RemoveRemoveAt 两个方法,它们似乎删除了行,但实际上只是将行从集合中移除。只有 Delete 方法才会将删除结果发回源数据库中。将以下代码粘贴到 SEND CHANGES TO SQL SERVER 代码之后:
    //*****************
    //BEGIN DELETE CODE 
    
    drCurrent = tblAuthors.Rows.Find("993-21-3427");
    drCurrent.Delete();
    Console.WriteLine("Record deleted successfully, Click any key to continue!!"); 
    Console.ReadLine();
    
    //END DELETE CODE 
                                            
    
  9. 将这些更改发送到 SQL Server 以移除早先添加的记录。将以下代码粘贴到 DELETE 代码之后:
    //*****************
    // CLEAN UP SQL SERVER
    daAuthors.Update(dsPubs, "Authors");
    Console.WriteLine("SQL Server updated successfully, Check Server explorer to see changes");
    Console.ReadLine();
                                            
    
  10. 保存项目。
  11. 在"调试"菜单上单击"启动"运行该项目。请注意,将出现几个消息框,它们指示代码的执行进度并让您能够在代码执行过程中查看数据的当前状态。

完整代码列表

using System;
using System.Data;
using System.Data.SqlClient;

namespace PopulateDataSet
{

    /// <summary>
    /// Summary description for Class1.
    /// </summary>
    class Class1
    {
        static void Main(string[] args)
        {
            string sConnectionString;

            // Modify the following string to correctly connect to your SQL Server.
            sConnectionString = "Password=;User ID=sa;"
                + "Initial Catalog=pubs;"
                + "Data Source=(local)";

            SqlConnection objConn
                = new SqlConnection(sConnectionString);
            objConn.Open();

            // Create an instance of a DataAdapter.
            SqlDataAdapter daAuthors 
                = new SqlDataAdapter("Select * From Authors", objConn);

            // Create an instance of a DataSet, and retrieve 
            // data from the Authors table.
            DataSet dsPubs = new DataSet("Pubs");
            daAuthors.FillSchema(dsPubs,SchemaType.Source, "Authors");
            daAuthors.Fill(dsPubs,"Authors"); 
            //****************
            // BEGIN ADD CODE 
            // Create a new instance of a DataTable.
            DataTable tblAuthors;
            tblAuthors = dsPubs.Tables["Authors"];

            DataRow drCurrent;
            // Obtain a new DataRow object from the DataTable.
            drCurrent = tblAuthors.NewRow();

            // Set the DataRow field values as necessary.
            drCurrent["au_id"] = "993-21-3427";
            drCurrent["au_fname"] = "George";
            drCurrent["au_lname"] = "Johnson";
            drCurrent["phone"] = "800 226-0752";
            drCurrent["address"] = "1956 Arlington Pl.";
            drCurrent["city"] = "Winnipeg";
            drCurrent["state"] = "MB";
            drCurrent["contract"] = 1;

            // Pass that new object into the Add method of the DataTable.
            tblAuthors.Rows.Add(drCurrent);
            Console.WriteLine("Add was successful, Click any key to continue!!");
            Console.ReadLine();

            // END ADD CODE   
            //*****************
            // BEGIN EDIT CODE 

            drCurrent = tblAuthors.Rows.Find("213-46-8915");
            drCurrent.BeginEdit();
            drCurrent["phone"] = "342" + drCurrent["phone"].ToString().Substring(3);
            drCurrent.EndEdit();
            Console.WriteLine("Record edited successfully, Click any key to continue!!");
            Console.ReadLine();
                        
            // END EDIT CODE   
            //*****************
            // BEGIN SEND CHANGES TO SQL SERVER 

            SqlCommandBuilder objCommandBuilder = new SqlCommandBuilder(daAuthors);
            daAuthors.Update(dsPubs, "Authors");
            Console.WriteLine("SQL Server updated successfully, Check Server explorer to see changes");
            Console.ReadLine();
                        
            // END SEND CHANGES TO SQL SERVER 
            //*****************
            //BEGIN DELETE CODE 

            drCurrent = tblAuthors.Rows.Find("993-21-3427");
            drCurrent.Delete();
            Console.WriteLine("SRecord deleted successfully, Click any key to continue!!"); 
            Console.ReadLine();
       
            //END DELETE CODE  
            //*****************
            // CLEAN UP SQL SERVER
            daAuthors.Update(dsPubs, "Authors");
            Console.WriteLine("SQL Server updated successfully, Check Server explorer to see changes");
            Console.ReadLine();                 
                        
        }
    }
}
                                

参考

有关使用 ADO.NET、DataSet 对象和 SQL 的更多信息,请访问下面的 Microsoft 网站: 深入了解数据访问(MSDN 之音专栏)http:...

有关使用 ADO.NET、DataSet 对象和 SQL 的更多信息,请访问下面的 Microsoft 网站:
深入了解数据访问(MSDN 之音专栏)
http://msdn.microsoft.com/columns/ (http://msdn.microsoft.com/columns/)
面向 ADO 程序员的 ADO.NET
http://msdn.microsoft.com/library/default.asp?url=/library/zh-cn/dndotnet/html/adonetprogmsdn.asp (http://msdn.microsoft.com/library/default.asp?url=/library/zh-cn/dndotnet/html/adonetprogmsdn.asp)
posted on 2009-07-27 11:37  vibratea  阅读(409)  评论(0编辑  收藏  举报