2

我有一个带有“Id”列的 DataTable,它是我们 SQL Server 2005 数据库中的一个标识列。此列的 AutoIncrement 属性设置为 true。我没有用数据库中的数据填充表,因为我只将它用于插入,所以它从 1 开始分配虚假 ID。

但是在我调用 tableAdapter.Update() 之后,我希望在该列中有由数据库分配的 REAL Id。

出于某种原因,只有第一行得到更新,其余的都没有。该表使用级联 DataRelation(分层结构)引用自身,并且对第一行的引用也会更新。

请告诉我如何相应地更新所有 ID。

提前致谢!

插入语句:

INSERT INTO Components (ComponentId, OrderNo, SerialNo) 
VALUES (@ComponentId, @OrderNo, @SerialNo) 

这里是组件表的架构:

Id BIGINT PK, 
ComponentId BIGINT FK, 
OrderNo int, 
SerialNo int 

请注意,Id 列的名称是“Id”,“ComponentId”是 FK 引用列。

4

4 回答 4

4

这曾经非常容易。您只需将 Column.AutoIncrementSeed 和 Column.AutoIncrementStep 都设置为“-1”。这样,添加的新行的 ID 将为 -1、-2 等。那么您的存储过程或 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

然而,微软以其无限智慧通过 ADO.NET 4.0 将这一切变得更糟。我不确定它何时更改,但他们现在在 AutoIncrement 列上有一个底层私有字段,该字段存储该列的当前值。因此,假设在数据库中,最后插入的值为“52”,那么现在将隐藏在 AutoIncrement 列中。这导致现在多用户应用程序出现巨大问题,我不能再使用“-1”技巧了,因为它从最后一个 AutoIncrement 值开始倒数。我什至试图通过反思来改变这一点,但没有任何好处。我讨厌微软在 ADO.NET 中打破了这一点,但他们坚持“不,我们不会修复 bug X [这不会”

于 2011-07-18T02:39:53.293 回答
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);
    }  
于 2009-09-08T10:55:34.143 回答
0

您必须从 SQL 中返回身份。但我不确定确切的语法了

尝试

INSERT INTO Components (ComponentId, OrderNo, SerialNo) 
VALUES (@ComponentId, @OrderNo, @SerialNo);
SET @ComponentId = SCOPE_IDENTITY()

或者

INSERT INTO Components (ComponentId, OrderNo, SerialNo) 
VALUES (@ComponentId, @OrderNo, @SerialNo);
SELECT SCOPE_IDENTITY()
于 2009-09-08T11:22:31.593 回答
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;
   }                 
}
于 2009-09-08T12:44:38.913 回答