通过DataTable.Rows.Add( row.ItemArray ) 出现“列“ID”被约束为是唯一的。值 xx 已存在。”的问题。
1.回顾数据库知识:当一个表,已经有一个名为ID的自增主键,接着,我们要插入新数据时,新数据是不能带有ID值的。这样,数据库才能自动给新数据,按照自增ID的顺序,赋值新ID。
举个例子,表:
struct
{
int ID, 自增;
varchar Content;
}
如果目前表里已经存在数据:
ID Content
1 X1
2 X2
3 X3
此时,我们插入数据:(ID=null,Content='X4'),则这条数据,插入数据库后,ID会自动被赋值为4。这也是我们希望得到的结果,并且也是规范操作方式。
但是,如果我们插入数据:(ID=5,Content='X4'),则这条数据,在部分数据库产品中,ID会保持为5。此时,数据库中就不存在ID=4的数据了,白白浪费了一个“位置”。
2.在C#中,使用 DataTable.Rows.Add( row.ItemArray )时,假设row的ID已经有了一个值,为99。此时,如果DataTable中的Row数据,不包含ID=99的数据,则插入能顺利完成。但如果包含了,则会报错:“列“ID”被约束为是唯一的。值 99 已存在。”。这是因为,DataTable的Row,沿用了数据库的约束:ID是不能重复的。所以,DataTable的Row里已经包含了ID=99的数据,此时,如果再插入条ID=99的数据,比如row,它的 ID=99,因此,在DataTable.Rows.Add( row.ItemArray )时,就会报这个错误。
并且,即使DataTable目前数据的最大ID不是99,假设为66,则插入了ID为99的新数据后,DataTable的ID则从100开始,67至98这个范围的ID就被浪费了。
3.所以,这个问题的症结在于,要插入新数据,必须让数据库来生成一个ID。对于DataTable,我们应该使用DataTable的NewRow(),或在数据集模式下的NewXXXRow(),来获取一个新ID。
代码:
DataRow newRow = DataTable.NewRow(); row.ID = newRow.ID; DataTable.Rows.Add(row.ItemArray);