簡體   English   中英

如何使用自動遞增鍵更新update語句的並發問題?

[英]How do I get rid of the concurrency issue with update statements with an auto-incrementing key?

我在運行時使用我的新手的Sql / Visual C#數據庫程序遇到以下錯誤消息:

並發沖突:UpdateCommand影響了預期的1條記錄中的0條。

我已經做了一些關於這個問題的搜索並且已經看到了幾個關於它的線索,但它們還不足以讓我解決這個問題。 我注意到人們在談論當你使用自動遞增主鍵時經常會發生的事情。 這個程序就是這種情況。 此外,沒有多線程或其他任何類似的東西,我正在編寫這個程序。 因此我認為自動增量可能是唯一的問題。

話雖這么說,盡管自動增加,我如何使更新命令工作? 在數據庫編程方面我幾乎站不起來,所以如果你不介意的話請詳細說明。 我正在使用的命令是通過SqlCommandBuilder對象。 我已將該對象設置為新的SqlCommandBuilder(DataAdapter),並且我沒有對它做任何特殊操作。

謝謝。


這個編輯是第二個。 第一個在下面。

由於我對數據庫編程經驗不足,我無法肯定地說出來。 但是我有充分的理由相信我遇到的問題與新的行沒有完全添加到數據庫,直到程序終止。 我不明白他們為什么要等到程序終止才能這樣做,或者如果他們等到那時,那么程序的終止到底是什么導致它們突然被完全保存。 但是我忘了提到這個錯誤只發生在我在程序的特定執行過程中添加的行上。 如果該行已經在先前的執行中添加或者通過預先存在的表數據添加,那么一切都很好。 我使用delete方法得到了同樣的錯誤,它也只出現在新行中。

如何將這些行完全保存到所有內容中,以免發生這種情況? 該程序的終止是什么導致這些行被完全保存? 謝謝!


由於請求,我在這里留下了兩個代碼片段。 第一個是問題發生的方法。 下一個將包括整個班級。 整個程序中只有兩個類,而另一個類在這個特定問題中對我來說似乎並不重要。

    private void btnUpdate_Click(object sender, EventArgs e)
    {
        if (recordShown)
        {
            con.Open();

            currentRow[1] = tbFirstName.Text;
            currentRow[2] = tbMiddleName.Text;
            currentRow[3] = tbLastName.Text;
            currentRow[4] = tbSuffix.Text;
            currentRow[5] = tbHomePhone.Text;
            currentRow[6] = tbCellPhone.Text;
            currentRow[7] = tbOtherPhone.Text;
            currentRow[8] = tbStreetAddress.Text;
            currentRow[9] = tbCityAndState.Text;
            currentRow[10] = tbCountry.Text;
            currentRow[11] = tbEmail.Text;

            dAdapter.Update(dataset, "Contacts");

            con.Close();
        }
        else
        {
            MessageBox.Show("Please locate/add a record first.");
        }
    }

下一個片段:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;

namespace Dakota
{
public partial class Form1 : Form
{
    SqlConnection con;
    DataSet dataset;
    SqlDataAdapter dAdapter;
    DataRow currentRow;
    string primaryKey;
    SqlCommandBuilder cmdBuilder;
    bool recordShown = false;

    public Form1()
    {
        InitializeComponent();
    }

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

        con.ConnectionString = "Data Source=.\\SQLEXPRESS;" +
            "AttachDbFilename=C:\\Users\\Sterling\\Documents\\Contacts.mdf;" +
            "Integrated Security=True;Connect Timeout=30;User Instance=True";

        con.Open();

        string getData = "SELECT * FROM tblContacts";
        dAdapter = new SqlDataAdapter(getData, con);
        dAdapter.Fill(dataset, "Contacts");
        cmdBuilder = new SqlCommandBuilder(dAdapter);
        cmdBuilder.ConflictOption = ConflictOption.OverwriteChanges;

        con.Close();
    }

    private void clearTextBoxes()
    {
        tbFirstName.Clear();
        tbMiddleName.Clear();
        tbLastName.Clear();
        tbSuffix.Clear();
        tbHomePhone.Clear();
        tbCellPhone.Clear();
        tbOtherPhone.Clear();
        tbStreetAddress.Clear();
        tbCityAndState.Clear();
        tbCountry.Clear();
        tbEmail.Clear();
    }

    private void fillTextBoxes(int row)
    {
        DataRow dr = dataset.Tables["Contacts"].Rows[row];
        tbFirstName.Text = dr.ItemArray.GetValue(1).ToString();
        tbMiddleName.Text = dr.ItemArray.GetValue(2).ToString();
        tbLastName.Text = dr.ItemArray.GetValue(3).ToString();
        tbSuffix.Text = dr.ItemArray.GetValue(4).ToString();
        tbHomePhone.Text = dr.ItemArray.GetValue(5).ToString();
        tbCellPhone.Text = dr.ItemArray.GetValue(6).ToString();
        tbOtherPhone.Text = dr.ItemArray.GetValue(7).ToString();
        tbStreetAddress.Text = dr.ItemArray.GetValue(8).ToString();
        tbCityAndState.Text = dr.ItemArray.GetValue(9).ToString();
        tbCountry.Text = dr.ItemArray.GetValue(10).ToString();
        tbEmail.Text = dr.ItemArray.GetValue(11).ToString();
    }

    private void fillTextBoxes(DataRow dr)
    {
        tbFirstName.Text = dr.ItemArray.GetValue(1).ToString();
        tbMiddleName.Text = dr.ItemArray.GetValue(2).ToString();
        tbLastName.Text = dr.ItemArray.GetValue(3).ToString();
        tbSuffix.Text = dr.ItemArray.GetValue(4).ToString();
        tbHomePhone.Text = dr.ItemArray.GetValue(5).ToString();
        tbCellPhone.Text = dr.ItemArray.GetValue(6).ToString();
        tbOtherPhone.Text = dr.ItemArray.GetValue(7).ToString();
        tbStreetAddress.Text = dr.ItemArray.GetValue(8).ToString();
        tbCityAndState.Text = dr.ItemArray.GetValue(9).ToString();
        tbCountry.Text = dr.ItemArray.GetValue(10).ToString();
        tbEmail.Text = dr.ItemArray.GetValue(11).ToString();
    }

    private void btnSearch_Click(object sender, EventArgs e)
    {
        string searchFor = tbSearchFor.Text;
        string column;
        if (rbFirstName.Checked)
        {
            column = "firstName";
        }
        else
        {
            column = "lastName";
        }

        DataRow[] rows = dataset.Tables["Contacts"].Select(column + "='" + searchFor + "'");
        int number = rows.Length;

        if (number == 0)
        {
            MessageBox.Show("No such records were found.");
        }
        else if (number > 1)
        {
            string[] strings = new string[rows.Length];
            for (int i = 0; i < strings.Length; i++)
            {
                bool hasFirst = false;
                bool hasMiddle = false;

                strings[i] = "";
                if (rows[i].ItemArray.GetValue(1).ToString() != "")
                {
                    hasFirst = true;
                    strings[i] += rows[i].ItemArray.GetValue(1).ToString();
                }
                if (rows[i].ItemArray.GetValue(2).ToString() != "")
                {
                    hasMiddle = true;
                    if (hasFirst)
                    {
                        strings[i] += " ";
                    }
                    strings[i] += rows[i].ItemArray.GetValue(2).ToString();
                }
                if (rows[i].ItemArray.GetValue(3).ToString() != "")
                {
                    if ((hasFirst && !hasMiddle) || (hasMiddle))
                    {
                        strings[i] += " ";
                    }
                    strings[i] += rows[i].ItemArray.GetValue(3).ToString();
                }
                if (rows[i].ItemArray.GetValue(4).ToString() != "")
                {
                    strings[i] += " " + rows[i].ItemArray.GetValue(4).ToString();
                }
            }

           // int choice;
            Form2 form2 = new Form2(strings);
            if (form2.ShowDialog(this) == DialogResult.OK)
            {
                primaryKey = rows[form2.choice].ItemArray.GetValue(0).ToString();
               // choice = form2.choice;
                fillTextBoxes(rows[form2.choice]);
                currentRow = rows[form2.choice];
                recordShown = true;
            }
        }            
        else
        {
            primaryKey = rows[0].ItemArray.GetValue(0).ToString();
            currentRow = rows[0];
            fillTextBoxes(rows[0]);
            recordShown = true;
        }
    }

    private void btnAdd_Click(object sender, EventArgs e)
    {
        con.Open();

        DataRow row = dataset.Tables["Contacts"].NewRow();
        row[1] = tbFirstName.Text;
        row[2] = tbMiddleName.Text;
        row[3] = tbLastName.Text;
        row[4] = tbSuffix.Text;
        row[5] = tbHomePhone.Text;
        row[6] = tbCellPhone.Text;
        row[7] = tbOtherPhone.Text;
        row[8] = tbStreetAddress.Text;
        row[9] = tbCityAndState.Text;
        row[10] = tbCountry.Text;
        row[11] = tbEmail.Text;
        currentRow = row;

        dataset.Tables["Contacts"].Rows.Add(row);
        dAdapter.Update(dataset, "Contacts");
        recordShown = true;

        con.Close();
    }

    private void btnUpdate_Click(object sender, EventArgs e)
    {
        if (recordShown)
        {
            con.Open();

            currentRow[1] = tbFirstName.Text;
            currentRow[2] = tbMiddleName.Text;
            currentRow[3] = tbLastName.Text;
            currentRow[4] = tbSuffix.Text;
            currentRow[5] = tbHomePhone.Text;
            currentRow[6] = tbCellPhone.Text;
            currentRow[7] = tbOtherPhone.Text;
            currentRow[8] = tbStreetAddress.Text;
            currentRow[9] = tbCityAndState.Text;
            currentRow[10] = tbCountry.Text;
            currentRow[11] = tbEmail.Text;

            dAdapter.Update(dataset, "Contacts");

            con.Close();
        }
        else
        {
            MessageBox.Show("Please locate/add a record first.");
        }
    }

    private void btnDelete_Click(object sender, EventArgs e)
    {
        con.Open();

        currentRow.Delete();
        dAdapter.Update(dataset, "Contacts");
        clearTextBoxes();
        recordShown = false;

        con.Close();
    }
}
}

謝謝!

這是一個解釋,但我不確定它是否正是你所看到的:

http://blogs.msdn.com/b/spike/archive/2010/04/07/concurrency-violation-the-updatecommand-affected-0-of-the-expected-1-records.aspx

這可能會更加正常,如果是這樣,則指出在聲明cmdBuilder之后應該出現的一些缺失行:

dAdapter.UpdateCommand = cmdBuilder.GetUpdateCommand();
dAdapter.InsertCommand = cmdBuilder.GetInsertCommand();
dAdapter.DeleteCommand = cmdBuilder.GetDeleteCommand();

http://www.codeguru.com/forum/archive/index.php/t-337168.html

此外,您可能需要致電:

dAdapter.Fill(dataset, "Contacts");

所有三個操作(插入,更新和刪除)的con.Close()之前。


在一個不相關的說明中,您可以通過將“fillTextBoxes(int row)”方法更改為以下來減少重復代碼:

private void fillTextBoxes(int row)
{
  DataRow dr = dataset.Tables["Contacts"].Rows[row];
  fillTextBoxes(dr);
}

有幾件事情,看起來你在調用update時沒有將它傳回你的標識列的ID。 在進行更新時是不是需要知道ID?

除了srutzky關於fillTextBoxes中冗余代碼的注釋之外,您還可以考慮不按順序值引用列,而是通過實際列名引用它們。 如果要向數據庫添加一個列,它將破壞所有正在執行以下操作的代碼:

tbLastName.Text = dr.ItemArray.GetValue(3).ToString();

相反,您可能會執行以下操作:

tbLastName.Text = dr.ItemArray.GetValue("LastName").ToString();

我不知道GetValue是否將列名作為參數,但我確信它是這樣的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM