#c# #sql #database
#c# #sql #База данных
Вопрос:
Он все,
Недавно я запустил проект, которому требуется много данных. На самом деле так много, что это не может быть сохранено в памяти среды выполнения. Я искал решения этой проблемы и выбрал для использования базы данных SQL. Я нашел руководство, объясняющее, как они работают, и воссоздал его сам. Это гарантирует синхронизацию вашей физической базы данных и виртуального набора данных с помощью DataAdapter для обновления базы данных;
(К вашему сведению, руководство можно найти здесь:http://www.homeandlearn.co.uk/csharp/csharp_s12p1.html );
Однако при расширении руководства я столкнулся с ошибкой, которую не могу объяснить, а именно: исключение DBConcurrencyException.
Когда я запускаю программу, все функциональные возможности работают, я могу добавлять строку и удалять строку. Но когда я пытаюсь выполнить оба в одном и том же исполнении (order = добавить, затем удалить), появляется ошибка. В нем описывается, что команда DeleteCommand затронула ноль из одной ожидаемой записи.
Я использовал следующие фрагменты кода:
Инициализация:
private void Form1_Load(object sender, EventArgs e)
{
con = new SqlConnection();
ds1 = new DataSet();
con.ConnectionString = "Data Source=.\SQLEXPRESS;AttachDbFilename=C:\<Private>\MyWorkers.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True";
con.Open();
string sql = "SELECT * From tblWorkers";
da = new SqlDataAdapter(sql, con);
da.Fill(ds1, "Workers");
NavigateRecords();
MaxRows = ds1.Tables["Workers"].Rows.Count;
updateIndicator();
con.Close();
//con.Dispose();
}
(Примечание: Я закомментировал каталог по соображениям конфиденциальности);
Добавление строки выполняется следующим образом:
private void btnSave_Click(object sender, EventArgs e)
{
SqlCommandBuilder cb = new SqlCommandBuilder(da);
DataRow dRow = ds1.Tables["Workers"].NewRow();
dRow[1] = textBox1.Text;
dRow[2] = textBox2.Text;
dRow[3] = textBox3.Text;
ds1.Tables["Workers"].Rows.Add(dRow);
MaxRows = MaxRows 1;
inc = MaxRows - 1;
da.Update(ds1, "Workers");
MessageBox.Show("Entry Added");
}
При удалении строки выполняется этот код:
private void btnDelete_Click(object sender, EventArgs e)
{
SqlCommandBuilder cb = new SqlCommandBuilder(da);
ds1.Tables["Workers"].Rows[inc].Delete();
MaxRows--;
inc = 0;
NavigateRecords();
da.Update(ds1, "Workers");
MessageBox.Show("Record Deleted");
}
Методы NavigateRecord() и setIndicator() не имеют отношения к этому вопросу, поскольку они являются элементами GUI.
Заранее всем спасибо!
Комментарии:
1. Как вы пытаетесь выполнить их оба одновременно? Я предполагаю, что ваша функция add завершается с ошибкой, а затем delete выдает эту ошибку.
2. Это не кажется хорошей идеей. Почему вы удаляете запись, основанную на статической переменной, указывающей индекс записи в datatable (
inc
)? Что произойдет, если кто-то добавит две записи подряд перед нажатием кнопки удаления?
Ответ №1:
Я наткнулся на это вопрос заявление при поиске способа предотвратить блокировку SQL Server всей записи (я хочу, чтобы она блокировалась по значению поля / столбца вместо этого) и заметил, что ответа не было дано, так что держи, если кто-нибудь еще столкнется с этой проблемой:
OP на самом деле не задавал вопрос, а только указал, в чем проблема; итак, вот ответ на вопрос, который не был задан «Как мне предотвратить нарушения параллелизма базы данных?»:
Нарушения параллелизма базы данных (в данном случае) можно предотвратить, приняв решение о том, какие данные должны поступать в базу данных. Большинство людей выбирают подход, который «последний в wins». Итак, при обработке операций с использованием TableAdapter поместите обновление в Try / Catch и во время Catch для исключения DBConcurrencyException просто убедитесь, что вы выполнили быстрое заполнение, затем измените все, что вы должны были изменить, а затем выполните обновление. Срабатывает каждый раз.