我的源码如下:
string selectquery="select * from Test;";
string connstring="server=tl;uid=sa;pwd=123456;database=DataBase";
SqlConnection conn=new SqlConnection(connstring);
//SqlCommand cmd=new SqlCommand(selectquery,conn);
SqlDataAdapter dataadapter1=new SqlDataAdapter(selectquery,conn);
DataSet DataSet1=new DataSet();
dataadapter1.Fill(DataSet1,"Test");
            DataSet1.Tables["test"].Rows[0][0]="122";
dataadapter1.Update(DataSet1.Tables["test"]);
DataGrid1.DataSource=DataSet1.Tables["Test"].DefaultView;
DataGrid1.DataBind();
运行后的错误为:
当传递具有已修改行的 DataRow 集合时,更新要求有效的 UpdateCommand。 
说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。 异常详细信息: System.InvalidOperationException: 当传递具有已修改行的 DataRow 集合时,更新要求有效的 UpdateCommand。源错误: 
dataadapter1.Update(DataSet1.Tables["test"]);

解决方案 »

  1.   

    使用Update方法要在正确生成了UpdateCommand,InsertCommand,DeleteCommand命令的前提下才行。
      

  2.   

    1. 打开 Microsoft Visual Studio .NET。 
    2. 在 Visual C# .NET 中新建控制台应用程序。默认情况下,Visual Studio 创建一个“静态类”和一个空的 Main() 过程。 
    3. 确保项目包括一个对 System 和 System.Data 命名空间的引用。在 System、System.Data 和 System.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. 现在已经加载了数据,您可以对其进行修改。添加行(或记录)有多种方法。该代码示例使用一个三步式过程: a.  &#8226; 从 DataTable 获取新的 DataRow 对象。 
    &#8226; 根据需要设置 DataRow 字段值。 
    &#8226; 将新的对象传递给 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 之后,可对列进行修改。您不必包装 BeginEdit 和 EndEdit 中的修改,但包装可简化 DataSet 必须完成的工作,并让 DataSet 可以在调用 EndEdit 的同时执行其验证检查。将以下代码粘贴到 ADD 代码之后://*****************
    // BEGIN EDIT CODEdrCurrent = 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 对象的 InsertCommand、UpdateCommand 和 DeleteCommand 属性。可手动编写 SQL 并用相应的 SqlCommand 对象填充这三个属性,但也可以使用 Visual Studio .NET 自动生成这三个命令。若要在需要时生成所需的命令,必须创建 SqlCommandBuilder 对象的实例并使用该构造函数中的 DataAdapter。如果想使用此方法(在以下代码示例中阐释),您的表必须有主键信息。要访问主键信息,可调用 FillSchema,然后将 DataAdapter 的 MissingSchemaAction 属性设置为 AddWithKey,或在代码中手动设置主键。将以下代码粘贴到 EDIT 代码之后://*****************
    // BEGIN SEND CHANGES TO SQL SERVERSqlCommandBuilder 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 集合包含 Remove 和 RemoveAt 两个方法,它们似乎删除了行,但实际上只是将行从集合中移除。只有 Delete 方法才会将删除结果发回源数据库中。将以下代码粘贴到 SEND CHANGES TO SQL SERVER 代码之后://*****************
    //BEGIN DELETE CODEdrCurrent = 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. 在调试菜单上单击启动运行该项目。请注意,将出现几个消息框,它们指示代码的执行进度并让您能够在执行过程中查看数据的当前状态。