如何更新数据集Parent和;具有自动生成标识密钥的子表?

时间:2009-05-31 08:18:05

标签: .net vb.net ado.net dataset

我在VB应用程序中使用ADO.NET数据集。我有一个带有一个父表和许多子表的类型化数据集。我想在将数据插入父表时生成身份密钥,然后使用相同的密钥(作为Foregin密钥)更新所有子表中的数据。

最后,我想更新数据库(SQL Server08)中的数据集。

嗯,首先可以直接在数据库中插入父表,获取Identity列,然后用于子表。

但我希望将其作为自动操作(如LINQ to SQL,它负责处理datacontext中的Primary& Foreign键。)

我可以在Dataset中处理父表和子表的Autogenerated列吗?

谢谢,

ABB

3 个答案:

答案 0 :(得分:4)

我认为这应该更加明显,并且应该在没有任何调整的情况下工作。但是,它仍然很容易。

解决方案分为两部分:

  1. 在子表和父表之间创建DataRelation,并将其设置为在更新时级联。 这样,只要父ID发生变化,所有孩子都会更新。

    Dim rel = ds.Relations.Add(parentTab.Columns("Id"), childTab.Columns("ParentId"))
    rel.ChildKeyConstraint.UpdateRule = Rule.Cascade
    
  2. 数据集插入和更新命令是双向的: 如果绑定了任何输出参数或返回了任何数据行, 它们将用于更新导致更新的数据集行。

    这对于此特定问题最有用:获取自动生成的列 回到申请表。 除了身份之外,这可能是例如时间戳列。 但身份是最有用的。

    我们需要做的就是设置insert命令来返回身份。 有几种方法可以做到,例如:

    a)将存储过程与输出参数一起使用。这是“真实”数据库中最便携的方式。

    b)使用多个SQL语句,最后一个返回插入的行。这是特定于SQL Server的AFAIK,但最简单的是:

    insert into Parent (Col1, Col2, ...) values (@Col1, @Col2, ...);
    select * from Parent where Id = SCOPE_IDENTITY();
    
  3. 设置完成后,您需要做的就是创建具有Id的父行,这些行是唯一的(在单个数据集中)但在数据库中是不可能的。负数通常是一个不错的选择。然后,当您将数据集更改保存到数据库时,所有新的父行都将从数据库中获得真正的Id


    注意:如果您碰巧使用数据库而没有多语句支持且没有存储过程(例如Access),则需要在父表适配器中的RowUpdated事件上设置事件处理程序。在hanler中,您需要使用select @@IDENTITY命令获得身份。


    一些链接:

答案 1 :(得分:3)

要指出的一切事情。

  1. 是的,您肯定需要为两个表分配关系。您可以从xsd编辑器中检查(双击您的xsd文件)。默认情况下,关系设置为“仅关系”,没有任何“更新规则”。通过进入“编辑关系”并选择“仅限外键约束”或“两者都~~~”来编辑此关系。并且需要将“更新规则”设置为Cascade! “删除规则”取决于您。

  2. 现在,当您将新的子表行的ID(AutoIncrement)用作新的子表行作为外键时,您必须先将父行添加到表中,然后再使用新的父行ID。

  3. 只要使用tableadapter为父表调用Update,关联的子表的新行就会自动具有正确的parentID。

  4. 我的简单代码片段:

    '--- Make Parent Row
    Dim drOrder as TOrderRow = myDS.TOder.NewTOrderRow
    drOrder.SomeValue = "SomeValue"
    myDS.TOrder.AddTOrderRow(drOrder) '===> THIS SHOULD BE DONE BEFORE CHILD ROWS
    
    '--- Now Add Child Rows!!! there are multiple ways to add a row into tables....
    myDS.TOrderDetail.AddTOrderDetailRow(drOrder, "detailValue1")
    myDS.TOrderDetail.AddTOrderDetailRow(drOrder, "detailvalue2")
    '....
    '....
    
    '--- Update Parent table first
    myTableAdapterTOrder.Update(myDS.TOrder)
    '--- As soon as you run this Update above for parent, the new parent row's AutoID(-1)
    '--- will become real number given by SQL server. And also new rows in child table will
    '--- have the updated parentID
    
    '--- Now update child table
    myTableAdapterTOrderDetail.Update(myDS.TOrderDetail)
    

    我希望它有所帮助!

答案 2 :(得分:0)

如果您不想使用数据集,并且还要将子ID分配给子项并获取ID,以便您可以更新模型: https://danielwertheim.wordpress.com/2010/10/24/c-batch-identity-inserts/