ADO.NET DataSet主键冲突

时间:2011-09-18 03:24:53

标签: c# ado.net dataset

我正在使用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 个答案:

答案 0 :(得分:2)

要强制执行任何约束(例如主键约束),您需要告知DataSet来自源的基础架构。为此,请在填写FillSchema()之前使用DataSet方法:

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

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");

有关详细信息,请参阅:

  

Updating Data Sources with DataAdapters