我正在使用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
答案 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");
有关详细信息,请参阅: