我有一个带有“Id”列的DataTable,它是我们的SQL Server 2005数据库中的标识列。此列的AutoIncrement属性设置为true。我没有用DB中的数据填充表格,因为我只将它用于插入,因此它从1开始分配伪造的ID。
但是在我调用tableAdapter.Update()之后,我想在该列中包含数据库分配的REAL ID。
由于某种原因,只有第一行得到更新,其余的都没有。 此表使用级联DataRelation(层次结构)引用自身,并且还更新对第一行的引用。
请告诉我如何相应地更新所有ID。
提前致谢!
INSERT语句:
INSERT INTO Components (ComponentId, OrderNo, SerialNo)
VALUES (@ComponentId, @OrderNo, @SerialNo)
这里是组件表的架构:
Id BIGINT PK,
ComponentId BIGINT FK,
OrderNo int,
SerialNo int
请注意,Id列的名称为“Id”,“ComponentId”是FK参考列。
答案 0 :(得分:4)
以前这很容易。您只需将Column.AutoIncrementSeed和Column.AutoIncrementStep BOTH设置为“-1”即可。这样,添加的新行将具有-1,-2等ID。然后,您的存储过程或TSQL代码将只是:
UPDATE Table
SET
Col1 = @Col1
Col2 = @Col2
WHERE (ID = @ID) -- If this is -1, -2, etc, it won't update
IF (@@ROWCOUNT = 0)
BEGIN
INSERT INTO Table(Col1, Col2) VALUES(Col1, Col2)
SET @ID = SCOPE_IDENTITY(); -- @ID would now change from -1 to 1, 2, 3, etc.
END
然而,微软在他们的infinte智慧中用ADO.NET 4.0改变了这一切。我不确定它何时发生了变化,但它们现在在AutoIncrement列上有一个底层私有字段,它存储该列的当前值。所以,让我们说在数据库中,最后插入的值为“52”,好吧,现在它将隐藏在AutoIncrement列中。现在这会导致多用户应用程序出现巨大问题,因为它从最后一个AutoIncrement值开始向后计数,所以我再也不能再使用“-1”技巧了。我甚至试图采用反思来改变这种情况,但这并不好。我讨厌微软在ADO.NET中打破了这个问题,但是他们坚持“不,我们不会修复错误X [这不会真正影响任何用户]但我们将实施一些全新的东西,这将搞砸所有你工作过的代码“。
答案 1 :(得分:0)
在执行Fill方法之前,创建一个带有自动增量的数据列,
编辑:
SqlConnection cn = new SqlConnection(@"Connection_String");
SqlDataAdapter adp;
SqlCommandBuilder cb;
DataTable dt;
private void Form3_Load(object sender, EventArgs e)
{
adp= new SqlDataAdapter("select * from temp", cn);
cb = new SqlCommandBuilder(adp);
dt = new DataTable();
dt.Columns.Add("SrNo", typeof(int));
dt.Columns[0].AutoIncrement = true;
dt.Columns[0].AutoIncrementSeed = 1;
dt.Columns[0].AutoIncrementStep = 1;
adp.Fill(dt);
dataGridView1.DataSource = dt;
}
private void button1_Click(object sender, EventArgs e)
{
adp.Update(dt);
}
答案 2 :(得分:0)
您必须从SQL返回Identity。但我不再确定语法了
尝试
INSERT INTO Components (ComponentId, OrderNo, SerialNo)
VALUES (@ComponentId, @OrderNo, @SerialNo);
SET @ComponentId = SCOPE_IDENTITY()
OR
INSERT INTO Components (ComponentId, OrderNo, SerialNo)
VALUES (@ComponentId, @OrderNo, @SerialNo);
SELECT SCOPE_IDENTITY()
答案 3 :(得分:0)
问题在于上面提到的DataRelation。出于某种原因,由于这个DataRelation,“子”行没有插入数据库中,并且它们的ID没有更新到实际ID,尽管DataTable有“刷新数据表”检查(在配置/高级设置中) )。
我删除了DataRelation并手动完成了所有工作。以下代码为我做了诀窍:
ComponentsTableAdapter cta = new ComponentsTableAdapter();
foreach (UpdaterDataSet.ComponentsRow r in uds.Components.Rows)
{
long origId = r.Id;
cta.Update(r);
foreach (UpdaterDataSet.ComponentsRow s in uds.Components.Rows)
{
if (s.Id != r.Id && !s.IsComponentIdNull() && s.ComponentId == origId)
s.ComponentId = r.Id;
}
}