并发冲突:UpdateCommand影响了预期的1条记录中的0条

时间:2010-08-02 13:14:12

标签: c# data-binding datagridview

我是c#的新手,并尝试将datagridview绑定到visual studio 2010中的mssql数据库。 数据绑定没问题,一切似乎都有效。除了一些奇怪的错误:

我在以下情况后得到了主题中的错误: 将同一行更新2次, 删除新插入的行, 删除其他行后更新行(对DeleteCommand的单词更改)

我在Google上找到的所有解决方案都不适合我。我希望有人可以帮助我。这是代码:

    private void fillDatagrid()
        {
            //fill datagrid ADO.NET
            conn = new SqlConnection(TestApp.Properties.Settings.Default.TestdatabaseConnectionString);
            cmd = conn.CreateCommand();
            conn.Open();
            cmd.CommandText = "SelectFrom";
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.Add("@table", SqlDbType.NVarChar, 50).Value = "Countries";
            cmd.Parameters.Add("@filters", SqlDbType.NVarChar, 300).Value = "";

            adapt = new SqlDataAdapter(cmd);
            dt = new DataTable();
            adapt.Fill(dt);
            dt.TableName = "Countries";

            conn.Close();

            BindingSource src = new BindingSource();
            src.DataSource = dt;
            dt.RowChanged += new DataRowChangeEventHandler(dt_RowChanged);

            dgDatabaseGrid.DataSource = src;
            dgDatabaseGrid.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
            //dgDatabaseGrid.RowValidating += new DataGridViewCellCancelEventHandler(dgDatabaseGrid_RowValidating);

            //disable columns:
            dgDatabaseGrid.Columns[0].Visible = false;
            dgDatabaseGrid.Columns["date_insert"].Visible = false;
            dgDatabaseGrid.Columns["user_insert"].Visible = false;
            dgDatabaseGrid.Columns["date_change"].Visible = false;
            dgDatabaseGrid.Columns["user_change"].Visible = false;
            dgDatabaseGrid.Columns["deleted"].Visible = false;

            //auto size last column
            dgDatabaseGrid.Columns["remarks"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;


            SqlCommandBuilder cb = new SqlCommandBuilder(adapt);
        }

        void dt_RowChanged(object sender, DataRowChangeEventArgs e)
        {
            try
            {
                adapt.Update(dt);
            }
            catch (SqlException ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }

private void dgDatabaseGrid_UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e)
        {
            if (!e.Row.IsNewRow)
            {


                DialogResult response = MessageBox.Show("Are you sure?", "Delete row?",
                                     MessageBoxButtons.YesNo,
                                     MessageBoxIcon.Question,
                                     MessageBoxDefaultButton.Button2);

                if (response == DialogResult.Yes)
                {

                    //ipv delete --> deleted=1
                    conn.Open();
                    cmd = conn.CreateCommand();
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.CommandText = "DeleteFrom";
                    cmd.Parameters.Add("@table", SqlDbType.NVarChar, 50).Value = "Countries";
                    cmd.Parameters.Add("@id", SqlDbType.Int).Value = e.Row.Cells[0].Value;
                    cmd.ExecuteNonQuery();
                    conn.Close();


                    //delete from datagrid:
                    dt.Rows[dgDatabaseGrid.SelectedCells[0].RowIndex].Delete();

                }

                //always cancel!
                e.Cancel = true;

            }
        }

5 个答案:

答案 0 :(得分:7)

我知道现在已经很晚了,但也许会有所帮助。

对您的代码进行了以下更改:

try
{
    adapt.Update(dt);

将这些行放在此处并使用您的变量

    Me.yourTableAdapter.Update(Me.yourDataSet.yourTable)
    Me.yourDataSet.youTable.AcceptChanges()
    Me.yourTableAdapter.Fill(Me.yourDataSet.yourTable)

它对我有用,希望它对你有用。

}
catch (SqlException ex)
{
    Debug.WriteLine(ex.Message);
}

答案 1 :(得分:1)

  

更新同一行2次后

是否有Timestamp列(或在Db服务器上更改/填充的任何其他列)?

当内存中的行与Db中的行不同时,可能会发生问题。而且因为你在SelectCmd上使用了SP(可能)在更新后没有刷新。

  

删除新插入的行

类似,导致在插入

后没有获取新ID
  

在删除另一行(更改为DeleteCommand的单词)

时更新行

完全不清楚。
但是为什么要手动删除行而不是将其留给adapt.Update()?你确定不是两种方法都被执行了吗?

答案 2 :(得分:1)

我已经在我的应用程序中追逐这个错误数星期了!我终于找到了我的问题。

我在申请表中找到的内容......

我有很多textboxescomboboxes等与数据绑定绑定。其中一些字段正在从其他字段的组合中更新。这一切都很有效,只有一个例外

  

如果在EndEdit之后重新计算了其中一个计算字段   在Update之前,这会导致dbconcurrency违规。

此错误并不意味着该行不再存在;它只是意味着它由于某种原因没有更新行。我的理由是数据有三种不同的状态,因此在我调用Update之前,它认为其他人已经更改了数据。

顺便说一句,这是位于用户计算机上的单个MDF,因此在更新期间没有其他人可以访问它来更改它。一个用户,One Update。我的代码是"其他"用户。

希望这可以帮助其他人指出正确的方向申请。

答案 3 :(得分:0)

如果我可以加上我的两分钱。

我一直在努力解决这个问题。在我们的应用程序中,我们计算了列,其中列是两个或更多其他列的计算结果。

这个Recalc扔了适配器。

我必须设置SqlCommandBuilder.ConflictOption = ConflictOption.OveriteChanges来解决这个问题。

我不知道是否有一个选项告诉Adapter在进行检查时忽略只读列。

答案 4 :(得分:-1)

简单回答:

  

这只是意味着如果您尝试更新数据库中不再存在的行。

更多细节可以在这里找到:http://blogs.msdn.com/b/spike/archive/2010/04/07/concurrency-violation-the-updatecommand-affected-0-of-the-expected-1-records.aspx