Нарушения первичного ключа ADO.NET DataSet - PullRequest
0 голосов
/ 18 сентября 2011

Я использую DataAdapter для заполнения DataSet из таблицы первичным ключом.

Если я изменяю значение в столбце первичного ключа на значение, которое уже существует в другой строке, я не получаю ошибку нарушения первичного ключа.

Если я вызываю DataSet.AcceptChanges() после изменениястрока, в которой теперь есть повторяющиеся значения первичного ключа, все еще нет ошибки нарушения первичного ключа.

Почему это так?

string sqlcommand = "select * from itemmaster";//itemaster contains id field which is primary key//

SqlConnection cn = new SqlConnection(connstring);
cn.Open();
SqlCommand cmd = new SqlCommand(sqlcommand, cn);

SqlDataAdapter da = new SqlDataAdapter(cmd);

DataSet ds = new DataSet();
da.Fill(ds);

ds.Tables[0].Rows[4]["ID"] = "2"; // value 2 already exists in another row

1 Ответ

2 голосов
/ 18 сентября 2011

Для применения любых ограничений, таких как ограничения первичного ключа, необходимо сообщить DataSet о базовой схеме из источника.Для этого используйте метод FillSchema() перед заполнением вашего DataSet:

da.FillSchema(ds, SchemaType.Source);
da.Fill(ds);

A DataSet - это просто несвязанный набор данных.

Когда вы вставляете, обновляете или удаляете строки из своего набора данных, вы фактически не обновляете базу данных напрямую.Вы просто фиксируете эти изменения в отключенном наборе данных.т.е. когда вы делаете это:

ds.Tables[0].Rows[4].Delete();
ds.AcceptChanges();

Все, что вы здесь сделали, - удалили строку из Table[0], а затем зафиксировали это изменение в DataSet, а не в самой базе данных.Чтобы зафиксировать это изменение в самой базе данных, вам нужно сделать что-то другое.

Вам необходимо добавить «команду удаления» в DataAdapter.Используя ваш код в качестве примера:

string sqlcommand = "select * from itemmaster";//itemaster contains id field which is primary key//

SqlConnection cn = new SqlConnection(connstring);
cn.Open();
SqlCommand cmd = new SqlCommand(sqlcommand, cn);

SqlDataAdapter da = new SqlDataAdapter(cmd);
SqlCommand deleteCmd = new SqlCommand("DELETE FROM itemmaster WHERE ID = @ID", cn);
SqlParameter deleteParam = deleteCmd.Parameters.Add("@ID", SqlDbType.Int, 4, "ID");
deleteParam.SourceVersion = DataRowVersion.Original;
da.DeleteCommand = deleteCmd;

DataSet ds = new DataSet();
da.FillSchema(ds, SchemaType.Source, "itemmaster");
da.Fill(ds, "itemmaster");

ds.Tables[0].Rows[4].Delete();

da.Update(ds, "itemmaster");

Для получения дополнительной информации см .:

Обновление источников данных с помощью DataAdapters

...