在传递带有已修改行的DataRow集合时,Update需要有效的UpdateCommand

时间:2009-02-25 23:14:46

标签: c# .net tableadapter

所以我上周有这个工作。至少,我以为我做到了! DataGridView Update

然后我今天再次开始研究该项目并且正在进行

  

更新在传递DataRow集合时需要有效的UpdateCommand   修改过的行。

开启

scDB.SSIS_Configurations_StagingDataTable table = (scDB.SSIS_Configurations_StagingDataTable)stagingGrid.DataSource;
myStagingTableAdapter.Update(table);

StagingTableAdapter有一个额外的查询,它将'filter'作为参数。这用于填充DataGridView。在创建该查询的向导中,我看到“生成了更新”。我发现大多数有此错误的帖子都要求使用命令构建器生成更新语句。我该怎么办?

11 个答案:

答案 0 :(得分:18)

如果您正在更新的表上没有定义主键,也会显示此消息。

答案 1 :(得分:13)

我和Sam遇到了同样的问题。我有工作代码突然不再工作了。我不知道什么时候写它,但它必须自动推断更新命令,然后停止这样做。也许MS之间的服务包在我们从未注意到的版本之间。无论如何,我遇到的解决方案是使用(在我的情况下为oracle)OracleCommandBuilder,它将DataAdapter(在调用fill之后)作为构造函数的参数,然后调用GetUpdateCommand()并将其分配给DataAdapter上的UpdateCommand。

pseudocode:

DataAdapter da = new DataAdapter(...)
...
da.Fill();
da.UpdateCommand = new OracleCommandBuilder(da).GetUpdateCommand();
...
da.Update();

答案 2 :(得分:6)

错误非常直观:适配器需要有效的SQL Update语句。数据集设计者和CommandBuilders会为你生成这些,但手工制作一些SQL也没有错。

无论如何,您必须验证(调试器)仍然配置了Update语句以及它实际上是什么。它可能更像是SQL而不是C#问题。

编辑:Command Builder工具只处理直接,单表,Select语句。使用加入或任何花哨的东西都是你自己的。

答案 3 :(得分:6)

Dan的解决方法对我有用,但我可以使用SqlCommandBuilder代替OracleCommandBuilder:

DataAdapter da = new DataAdapter(...)
...
da.Fill();
da.UpdateCommand = new SqlCommandBuilder(da).GetUpdateCommand();
...
da.Update();

答案 4 :(得分:1)

我刚刚遇到了同样的问题,Jason的回答对我有用:我忘了为我的桌子分配一把主键。

再添一个提醒:在更正表中的问题后,当回到Visual Studio时,在包含数据集的.xsd文件中,确保删除原始表并从服务器再次添加它Explorer或Database Explorer。否则错误仍然存​​在。

答案 5 :(得分:1)

您应始终拥有主键定义的列字段。否则问题将永远存在。如果您没有主键字段,SqlCommandBuilder将无法帮助您。

答案 6 :(得分:0)

从页面:

  

注意如果主查询中有足够的信息,则   将创建InsertCommand,UpdateCommand和DeleteCommand命令   默认情况下,在生成TableAdapter时。如果是TableAdapter的话   主查询是多个表SELECT语句,它是   设计师可能无法生成InsertCommand,   UpdateCommand和DeleteCommand。如果未生成这些命令,   执行TableAdapter.Update时可能会收到错误   方法

据我所知,这些陈述应该已经生成。我正在使用一张桌子。

答案 7 :(得分:0)

我也遇到了同样的问题并得到了以下解决方案。试试吧。

private void btnSave_Click(object sender, EventArgs e)
{
    ConnStr = "Data Source=FIN03;Initial Catalog=CmsTest;Integrated Security=True";
    cn = new SqlConnection(ConnStr);
    cn.Open();
    SqlCommand cmd = new SqlCommand();
    cmd.Connection = cn;
    mytran = cn.BeginTransaction(IsolationLevel.Serializable );

    cmd.Transaction = mytran;
    try
    {

        scb = new SqlCommandBuilder(da);
        da.Update(ds, "tblworker");
        mytran.Commit ();
        MessageBox.Show("Data update successfully"); 

    }
    catch (Exception err)
    {

           mytran.Rollback();

            MessageBox.Show(err.Message.ToString());           
    }
}

答案 8 :(得分:0)

正如其他人所说,您需要确保在表上设置了要创建自动生成的更新代码的主键。我这样做了,但是仍然看到相同的消息

  

更新在传递DataRow集合时需要有效的UpdateCommand   修改后的行。

然后我发现您还需要刷新表适配器(考虑一下就可以了!)。

在执行此操作时,还应再次检查是否已选择 Generate Insert,Update和Delete语句选项(如下所示)。

enter image description here

然后只需单击向导,最后一个屏幕应确认它将创建重做所需的代码(现在带有主键):

enter image description here

答案 9 :(得分:-1)

您要做的就是编辑数据库,并确保至少有一列被标识为主键

在我的简单示例中,这可能是名称列-尽管实际上,我将添加一个自动编号标识列,以确保该列中的所有值都是唯一的。

保留所有内容,重新创建一个新的数据集, 使用拖放操作替换DataGridView ,就像以前一样,

和往常一样,答案一经得知就很简单,而您却一无所获。

Source

答案 10 :(得分:-1)

您可以对任何表使用以下代码,它会自动为您生成插入、更新和删除命令。

private void savechanges(String tbl, SqlDataAdapter sqldap, DataSet dset)
    {

        try
        {
            SqlCommandBuilder scb = new SqlCommandBuilder(sqldap);
            scb.ConflictOption = ConflictOption.CompareRowVersion;
            sqldap.Update(dset, tbl);
            dset.AcceptChanges();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message.ToString());
        }
    }