【问题标题】:DataAdapter.Update() does not Update the DatabaseDataAdapter.Update() 不更新数据库
【发布时间】:2011-10-13 13:55:21
【问题描述】:

我确定这条线路不工作有一个非常简单的原因,但过去一周它已经回避了,所以我希望其他人会注意到我的错。

我已经在这个项目上工作了几个星期到一个月。我一直在混合使用旧的 DataAdapter、CommandBuiler 等,在 1 个数据库上使用一些 linq to sql 编码,以及多个 Windows 应用程序表单。此特定表单使用 DataAdapter、Dataset 和 Command Builder 从数据库中编辑或删除行。它一直工作正常,直到我换了电脑。现在 Dataset 正在更新,但 Database 没有。

这是这个表格的完整代码:

private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
    if (MessageBox.Show("Exit Cook Book?", "Exit?", MessageBoxButtons.OKCancel) == DialogResult.OK)
    {
        Application.Exit();
    }
}

private void goBackToolStripMenuItem_Click(object sender, EventArgs e)
{
    AddRecipe goBack = new AddRecipe();

    Close();
    goBack.Show();
}

private void helpToolStripMenuItem_Click(object sender, EventArgs e)
{
    MessageBox.Show("Scan through the Cook Book to find recipes that you wish to edit or delete.", "Help!");
}

SqlConnection con;
SqlDataAdapter dataAdapt;
DataSet dataRecipe;
SqlCommandBuilder cb;

int MaxRows = 0;
int inc = 0;


private void EditRecipe_Load(object sender, EventArgs e)
{
    con = new SqlConnection();
    dataRecipe = new DataSet();

    con.ConnectionString = "Data Source=.\\SQLEXPRESS;AttachDbFilename=|DataDirectory|\\Recipes.mdf;Integrated Security=True;User Instance=True";

        con.Open();

        //MessageBox.Show("Database Open");

        string sql = "SELECT* From CookBookRecipes";
        dataAdapt = new SqlDataAdapter(sql, con);

        dataAdapt.Fill(dataRecipe, "CookBookRecipes");
        NavigateRecords();
        MaxRows = dataRecipe.Tables["CookBookRecipes"].Rows.Count;

        con.Close();
}


private void NavigateRecords()
{
    DataRow dRow = dataRecipe.Tables["CookBookRecipes"].Rows[inc];

    tbRName.Text = dRow.ItemArray.GetValue(0).ToString();
    listBox1.SelectedItem = dRow.ItemArray.GetValue(1).ToString();
    tbRCreate.Text = dRow.ItemArray.GetValue(2).ToString();
    tbRIngredient.Text = dRow.ItemArray.GetValue(3).ToString();
    tbRPrep.Text = dRow.ItemArray.GetValue(4).ToString();
    tbRCook.Text = dRow.ItemArray.GetValue(5).ToString();
    tbRDirections.Text = dRow.ItemArray.GetValue(6).ToString();
    tbRYield.Text = dRow.ItemArray.GetValue(7).ToString();
    textBox1.Text = dRow.ItemArray.GetValue(8).ToString();
}

private void btnNext_Click(object sender, EventArgs e)
{
    if (inc != MaxRows - 1)
    {
        inc++;
        NavigateRecords();
    }
    else
    {
        MessageBox.Show("That's the last recipe of your Cook Book!", "End");
    }
}

private void btnBack_Click(object sender, EventArgs e)
{
    if (inc > 0)
    {
        inc--;
        NavigateRecords();
    }
    else
    {
        MessageBox.Show("This is the first recipe of your Cook Book!", "Start");
    }
}

private void btnSave_Click(object sender, EventArgs e)
{
    cb = new SqlCommandBuilder(dataAdapt);

    DataRow daRow = dataRecipe.Tables["CookBookRecipes"].Rows[inc];

    daRow[0] = tbRName.Text;
    daRow[1] = listBox1.SelectedItem.ToString();
    daRow[2] = tbRCreate.Text;
    daRow[3] = tbRIngredient.Text;
    daRow[4] = tbRPrep.Text;
    daRow[5] = tbRCook.Text;
    daRow[6] = tbRDirections.Text;
    daRow[7] = tbRYield.Text;
    daRow[8] = textBox1.Text;

    if (MessageBox.Show("You wish to save your updates?", "Save Updates?", MessageBoxButtons.OKCancel) == DialogResult.OK)
    {

        dataAdapt.Update(dataRecipe, "CookBookRecipes");

        MessageBox.Show("Recipe Updated", "Update");
    }
}

private void btnDelete_Click(object sender, EventArgs e)
{
    SqlCommandBuilder cb;
    cb = new SqlCommandBuilder(dataAdapt);

    if (MessageBox.Show("You wish to DELETE this recipe?", "Delete?", MessageBoxButtons.OKCancel) == DialogResult.OK)
    {
        dataRecipe.Tables["CookBookRecipes"].Rows[inc].Delete();
        MaxRows--;
        inc = 0;
        NavigateRecords();

        dataAdapt.Update(dataRecipe, "CookBookRecipes");

        MessageBox.Show("Your Recipe has been Deleted", "Delete");
    }
}

这应该更新表格:

dataAdapt.Update(dataRecipe, "CookBookRecipes");

我没有收到任何错误,但数据表不会更新。

提前感谢您的帮助,如果您需要更多信息,请告诉我。

【问题讨论】:

  • 你有没有得到这个答案?我为处理数据库更新而构建的项目遇到了同样的问题。在一个项目中使用它,正如您所注意到的那样,它失败了。从另一个使用它,它工作正常。所以我真的很难过。我什至比较了两者中的 SqlAdapter.GetUpdateCommand().CommandText,它们与 ItemArray 数据元素完全相同。不过,我并不真正了解自动生成的 INSERT 命令中的所有参数。 RowStates 也是一样的。令人沮丧。

标签: c# database dataadapter


【解决方案1】:

为了更新数据库中的数据,您的 SqlDataAdapter 需要设置其 InsertCommand、UpdateCommand、DeleteCommand 属性。您创建的 SqlCommandBuilder 实例具有这些命令,但您需要将它们设置为您的 SqlDataAdapter。

在其他世界:介于两者之间

 SqlCommandBuilder cb;
 cb = new SqlCommandBuilder(dataAdapt);

 dataAdapt.Update(dataRecipe, "CookBookRecipes");

你需要

dataAdapt.DeleteCommand = cb.GetDeleteCommand(true);
dataAdapt.UpdateCommand = cb.GetUpdateCommand(true);
dataAdapt.InsertCommand = cb.GetInsertCommand(true);

【讨论】:

  • 搜遍了,没有人提到将命令生成器生成的查询绑定到数据适配器。谢谢你。
  • 请注意,如果在创建 SqlCommandBuilder 时指定 dataAdaptor,则不需要设置命令,SqlCommandBuilder 会将自己注册为侦听器。 Documentation
【解决方案2】:

更新的SqlCommand 是什么样的?我看到了命令,但没有看到任何 SqlText,这就是你所缺少的。

您需要通过在SqlDataAdapter 上设置.UpdateCommand 属性来定义.Update 的作用

这个链接很好地说明了如何去做: http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldataadapter.updatecommand.aspx

【讨论】:

  • SqlText?我会把它放在哪里?
【解决方案3】:

试试下面的来源。

private void btnSave_Click(object sender, EventArgs e)
{
    cb = new SqlCommandBuilder(dataAdapt);

    //Old source: DataRow daRow = dataRecipe.Tables["CookBookRecipes"].Rows[inc];

    //Added source code
    DataRow daRow = dataRecipe.Tables["CookBookRecipes"].NewRow();

    //Added source code
    dataRecipe.Tables["CookBookRecipes"].AddRow(daRow);

    daRow.BeginEdit();
    daRow[0] = tbRName.Text;
    daRow[1] = listBox1.SelectedItem.ToString();
    daRow[2] = tbRCreate.Text;
    daRow[3] = tbRIngredient.Text;
    daRow[4] = tbRPrep.Text;
    daRow[5] = tbRCook.Text;
    daRow[6] = tbRDirections.Text;
    daRow[7] = tbRYield.Text;
    daRow[8] = textBox1.Text;
    daRow.EndEdit();

    //Reset state of rows to unchanged
    dataRecipe.Tables["CookBookRecipes"].AcceptChanges();
    //Set modified. The dataAdapt will call update stored procedured 
    //for the row that has Modifed row state. 
    //You can also try SetAdded() method for new row you want to insert
    daRow.SetModified();

    if (MessageBox.Show("You wish to save your updates?", "Save Updates?", MessageBoxButtons.OKCancel) == DialogResult.OK)
    {

        dataAdapt.Update(dataRecipe, "CookBookRecipes");

        MessageBox.Show("Recipe Updated", "Update");
    }
}

【讨论】:

  • 我有时不得不使用批量更新,我总是忘记将行标记为已修改。这正是我们所需要的,谢谢您的提醒。
【解决方案4】:

在更新之前添加 AcceptChangesDuringUpdate 对我有用,例如:

foreach (string tableName in tableNames)
        {             
            da = new SqlDataAdapter("SELECT * FROM " + tableName, cn);
            cb = new SqlCommandBuilder(da); //initialise the update, insert and delete commands of da
            da.AcceptChangesDuringUpdate = true;
            da.Update(myDataSet, tableName);               
        }

【讨论】:

    【解决方案5】:

    你可能需要

    DataAdapeter.AcceptChanges()
    

    【讨论】:

    • DataAdapter 没有AcepptChanges() 方法。实际上,如果您调用该方法,例如从 DataSet before 调用 DataAdapter.Update() 方法,您会将所有行状态设置为 Unchanged并阻止DataAdapter.Update() 在修改的行中搜索标志,因此,阻止此方法选择适当的 INSERT、UPDATE、DELETE 命令。
    【解决方案6】:

    我遇到了同样的问题:用一些新行填充了一个新数据集,但更新时没有任何反应。我使用了类似的 MySqlDataAdapter。

    事实证明,当您需要 MySqlCommandBuilder 中的 InsertCommand 时,您必须将行状态指定为已添加。另见:MSDN

    【讨论】:

      【解决方案7】:
      //change this line
      
      DataRow daRow = dataRecipe.Tables["CookBookRecipes"].NewRow();
      
      daRow[0] = tbRName.Text;
      daRow[1] = listBox1.SelectedItem.ToString();
      daRow[2] = tbRCreate.Text;
      daRow[3] = tbRIngredient.Text;
      daRow[4] = tbRPrep.Text;
      daRow[5] = tbRCook.Text;
      daRow[6] = tbRDirections.Text;
      daRow[7] = tbRYield.Text;
      daRow[8] = textBox1.Text;
      
      if (MessageBox.Show("You wish to save your updates?", "Save Updates?", MessageBoxButtons.OKCancel) == DialogResult.OK)
      {
      //add & change this too
      dataRecipe.Tables["CookBookRecipes"].Rows.Add(daRow);
          dataAdapt.Update(dataRecipe, "CookBookRecipes");
      
          MessageBox.Show("Recipe Updated", "Update");
      }
      

      }

      【讨论】:

        【解决方案8】:

        我也遇到了同样的问题。我的 dataadapter.fill 有效,但 dataadapter.update 无效。我意识到问题是我的数据库表不包含主键。在我修改我的表以包含一个带有主键的列之后,dataadapter.fill 工作。 希望这对某人有所帮助。

        【讨论】:

          【解决方案9】:

          如果您使用的是 Local-DB,请检查数据库的属性。

          在“复制到输出目录”属性中设置值“如果较新则复制”,您就可以开始了。

          【讨论】:

            【解决方案10】:

            如果您正在使用的数据库已添加到您的项目中,则其“复制到输出目录”属性可能会设置为“始终复制”。

            如果是,请尝试将其更改为“如果较新则复制”。

            我从here得到了这个解决方案。

            【讨论】:

              猜你喜欢
              • 2020-07-25
              • 2012-04-04
              • 2015-07-21
              • 2013-10-25
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多