如何在 Visual C# .NET 中使用 SqlDataAdapter 对象更新 SQL Server 数据库

本文包含 Microsoft Visual C# .NET 代码示例,这些示例演示如何通过“SqlDataAdapter”对象,用运行在“DataSet”对象上的数据修改来 更新 SQL Server 数据库,其中“DataSet”对象使用该数据库中某个表的数据进行填充。

技术说明

“SqlDataAdapter”对象充当 ADO.NET“DataSet”对象和 SQL Server 数据库之间的桥梁。它是一个中间对象,可使用从 SQL Server 数据库检索到的数据填充 ADO .NET“DataSet”对象,然后更新数据库以反映通过使用“DataSet”对象对数据进行的更改(如插入、更新和删除)。

“SqlDataAdapter”对象的“InsertCommand”、“UpdateCommand”和“DeleteCommand”属性可使用运行在“DataSet”对象上的数据修改更新数据库。这些属性是用于指定 INSERT、UPDATE 和 DELETE Transact-SQL 命令的“SqlCommand”对象,而这些命令可用于将数据集修改传递到目标数据库。分配给这些属性的“SqlCommand”对象可通过代码手动创建,也可以通过使用“SqlCommandBuilder”对象自动生成。

本文中的第一个代码示例将演示如何使用“SqlCommandBuilder”对象自动生成“SqlDataAdapter”对象的“UpdateCommand”属性。第二个示例使用在其中不能应用自动命令生成的方案。它将演示如何手动创建“SqlCommand”对象并将其用作“SqlDataAdapter”对象的“UpdateCommand”属性。

创建示例 SQL Server 表

若要创建可用于本文中记录的 Visual C# .NET 代码示例的 SQL Server 表,请按下列步骤操作:

  1. 打开 SQL 查询分析器,然后将其连接到要在其中创建示例表的数据库。本文中的代码示例将使用 Microsoft SQL Server 附带的“Northwind”数据库。
  2. 若要创建名为 CustTest 的示例表,并向该表中插入记录,请运行下列 Transact-SQL 语句:
    Create Table CustTest
    (
     CustID int primary key,
     CustName varchar(20)
    )
    
    Insert into CustTest values(1,'John')
    					

代码示例 1:自动生成的命令

如果您在检索填充“DataSet”的数据时使用的 SELECT 语句基于一个单独的数据表,则可以使用“CommandBuilder”对象自动生成“DataAdapter”对象的“DeleteCommand”、“InsertCommand”和“UpdateCommand”属性。这将简化并减少执行“插入”、“更新”和“删除”操作所必需的代码。

作为最低要求,必须将“SelectCommand”属性设置为自动生成命令。“SelectCommand”检索的表架构将决定自动生成的 INSERT、UPDATE 和 DELETE 语句的语法。

“SelectCommand”属性还必须返回至少一个主键或唯一的列。如果什么也没有返回,则生成 InvalidOperation 异常,且不生成这些命令。

若要创建一个示例 Visual C# .NET 控制台应用程序,以演示如何使用“SqlCommandBuilder”对象自动为“SqlDataAdapter”对象的“SqlCommand”对象生成“DeleteCommand”、“InsertCommand”和“UpdateCommand”属性,请按下列步骤操作:

  1. 若要创建新的 Visual C# .NET 控制台应用程序,请按下列步骤操作:
    1. 启动 Microsoft Visual Studio .NET。
    2. 在“文件”菜单上,指向“新建”,然后单击“项目”。
    3. 单击“项目类型”下的“Visual C# 项目”,然后单击“模板”下的“控制台应用程序”。
  2. 将 Class1 的默认内容替换为以下代码:
    using System.Data;
    using System.Data.SqlClient;
    using System;
    namespace Q308507 {
    
      class Class1 {
         static void Main(string[] args)	{
      
            SqlConnection cn = new SqlConnection();
            DataSet CustomersDataSet = new DataSet();
            SqlDataAdapter da;
            SqlCommandBuilder cmdBuilder;
      
            //Set the connection string of the SqlConnection object to connect
            //to the SQL Server database in which you created the sample
            //table.
            cn.ConnectionString = "Server=server;Database=northwind;UID=login;PWD=password;";
    
            cn.Open();      
    
            //Initialize the SqlDataAdapter object by specifying a Select command 
            //that retrieves data from the sample table.
            da = new SqlDataAdapter("select * from CustTest order by CustId", cn);
    
            //Initialize the SqlCommandBuilder object to automatically generate and initialize
            //the UpdateCommand, InsertCommand, and DeleteCommand properties of the SqlDataAdapter.
            cmdBuilder = new SqlCommandBuilder(da);
    
            //Populate the DataSet by running the Fill method of the SqlDataAdapter.
            da.Fill(CustomersDataSet, "Customers");
    
            //Display the Update, Insert, and Delete commands that were automatically generated
            //by the SqlCommandBuilder object.
            Console.WriteLine("Update command Generated by the Command Builder : ");
            Console.WriteLine("==================================================");
            Console.WriteLine(cmdBuilder.GetUpdateCommand().CommandText);
            Console.WriteLine("         ");
    
            Console.WriteLine("Insert command Generated by the Command Builder : ");
            Console.WriteLine("==================================================");
            Console.WriteLine(cmdBuilder.GetInsertCommand().CommandText);
            Console.WriteLine("         ");        
    
            Console.WriteLine("Delete command Generated by the Command Builder : ");
            Console.WriteLine("==================================================");
            Console.WriteLine(cmdBuilder.GetDeleteCommand().CommandText);
    	Console.WriteLine("         ");
    
            //Write out the value in the CustName field before updating the data using the DataSet.
            Console.WriteLine("Customer Name before Update : " + CustomersDataSet.Tables["Customers"].Rows[0]["CustName"]);
    
            //Modify the value of the CustName field.
            CustomersDataSet.Tables["Customers"].Rows[0]["CustName"] = "Jack";
    
            //Post the data modification to the database.
            da.Update(CustomersDataSet, "Customers");        
    
            Console.WriteLine("Customer Name updated successfully");
    
            //Close the database connection.
            cn.Close();
    
            //Pause
            Console.ReadLine();
          }
       }
    
    }
  3. 根据您的环境相应地修改连接字符串。
  4. 在保存之后运行该应用程序。请注意,将打开一个控制台窗口,然后显示以下输出:
    Update command Generated by the Command Builder : 
    ==================================================
    UPDATE CustTest SET CustID = @p1 , CustName = @p2 WHERE ( CustID = @p3 AND CustName = @p4 )
             
    Insert command Generated by the Command Builder : 
    ==================================================
    INSERT INTO CustTest( CustID , CustName ) VALUES ( @p1 , @p2 )
             
    Delete command Generated by the Command Builder : 
    ==================================================
    DELETE FROM  CustTest WHERE ( CustID = @p1 AND CustName = @p2 )
          
    Customer Name before Update :John
    Customer Name updated successfully
    						
  5. 按任意键可关闭该控制台窗口并停止该应用程序

代码示例 2:手动创建并初始化 UpdateCommand 属性

代码示例 1 生成的输出表明,自动为 UPDATE 语句生成命令的逻辑基于开放式并发。就是说,这些记录不会被锁定以禁止编辑,其他用户或进程可以随时修改这些记录。

由于记录可在从 SELECT 语句返回后而在 UPDATE 语句发出之前进行修改,因此自动生成的 UPDATE 语句将包含一个 WHERE 子句,这样就只有包含所有原始值的行才会被更新。这样做的目的在于避免覆盖新数据。如果自动生成的 UPDATE 语句所尝试更新的行已被删除或不包含在“DataSet”中找到的原始值,则该命令将不影响任何记录,且将生成 DBConcurrencyException 异常。若要使用代码示例 1 中的代码测试上述情况,请在 Visual Studio 调试器中运行该代码,并在填充“DataSet”之后而更新数据库之前设置一个断点,然后从 SQL 查询分析器的表中删除这一行。随后“Update”调用将引发异常。

如果您希望在不考虑原始值的情况下完成 UPDATE 语句,则必须显式设置“DataAdapter”的“UpdateCommand”,同时不得依赖自动命令生成。

若要手动创建并初始化代码示例 1 中使用的“SqlDataAdapter”对象的“UpdateCommand”属性,请按下列步骤操作:

  1. 替换 Visual C# .NET 控制台应用程序中 Class1 的“Main”函数所包含的现有代码。该应用程序是在代码示例 1:自动生成的命令一节创建的。请将其替换为以下代码:
    SqlConnection cn = new SqlConnection();
    DataSet CustomersDataSet = new DataSet();
    SqlDataAdapter da;
    SqlCommand DAUpdateCmd;
    
    cn.ConnectionString = "Server=server;Database=northwind;UID=login;PWD=password;";
    cn.Open();
    
    da = new SqlDataAdapter("select * from CustTest order by CustId", cn);
    
    //Initialize the SqlCommand object that will be used as the UpdateCommand for the DataAdapter.
    
    //Note that the WHERE clause uses only the CustId field to locate the record to be updated.
    DAUpdateCmd = new SqlCommand("Update CustTest set CustName = @pCustName where CustId = @pCustId", da.SelectCommand.Connection);
    
    //Create and append the parameters for the Update command.
    DAUpdateCmd.Parameters.Add(new SqlParameter("@pCustName", SqlDbType.VarChar));
    DAUpdateCmd.Parameters["@pCustName"].SourceVersion = DataRowVersion.Current;
    DAUpdateCmd.Parameters["@pCustName"].SourceColumn = "CustName";
    
    DAUpdateCmd.Parameters.Add(new SqlParameter("@pCustId", SqlDbType.Int));
    DAUpdateCmd.Parameters["@pCustId"].SourceVersion = DataRowVersion.Original;
    DAUpdateCmd.Parameters["@pCustId"].SourceColumn = "CustId";
    
    //Assign the SqlCommand to the UpdateCommand property of the SqlDataAdapter.
    da.UpdateCommand = DAUpdateCmd;        
    da.Fill(CustomersDataSet, "Customers");        
    
    Console.WriteLine("Customer Name before Update : " + CustomersDataSet.Tables["Customers"].Rows[0]["CustName"]);
    CustomersDataSet.Tables["Customers"].Rows[0]["CustName"] = "Jack";
    da.Update(CustomersDataSet, "Customers");        
    
    Console.WriteLine("Customer Name updated successfully");
    
    cn.Close();
    Console.ReadLine();
    					
  2. 根据您的环境相应地修改连接字符串。
  3. 请重复代码示例 1:自动生成的命令一节中的步骤 1 到步骤 4。注意,将不再生成 DBConcurrencyException 异常。

 

 

另有方法请看: http://www.codeproject.com/KB/cs/CSharpAndTableValueParams.aspx

http://www.codeproject.com/KB/database/CreateDB.aspx

http://www.codeproject.com/KB/database/sqlserver2008.aspx

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值