我在VB应用程序中使用ADO.NET数据集。我有一个带有一个父表和许多子表的类型化数据集。我想在将数据插入父表时生成身份密钥,然后使用相同的密钥(作为Foregin密钥)更新所有子表中的数据。
最后,我想更新数据库(SQL Server08)中的数据集。
嗯,首先可以直接在数据库中插入父表,获取Identity列,然后用于子表。
但我希望将其作为自动操作(如LINQ to SQL,它负责处理datacontext中的Primary& Foreign键。)
我可以在Dataset中处理父表和子表的Autogenerated列吗?
谢谢,
ABB
答案 0 :(得分:4)
我认为这应该更加明显,并且应该在没有任何调整的情况下工作。但是,它仍然很容易。
解决方案分为两部分:
在子表和父表之间创建DataRelation
,并将其设置为在更新时级联。
这样,只要父ID发生变化,所有孩子都会更新。
Dim rel = ds.Relations.Add(parentTab.Columns("Id"), childTab.Columns("ParentId"))
rel.ChildKeyConstraint.UpdateRule = Rule.Cascade
数据集插入和更新命令是双向的: 如果绑定了任何输出参数或返回了任何数据行, 它们将用于更新导致更新的数据集行。
这对于此特定问题最有用:获取自动生成的列 回到申请表。 除了身份之外,这可能是例如时间戳列。 但身份是最有用的。
我们需要做的就是设置insert命令来返回身份。 有几种方法可以做到,例如:
a)将存储过程与输出参数一起使用。这是“真实”数据库中最便携的方式。
b)使用多个SQL语句,最后一个返回插入的行。这是特定于SQL Server的AFAIK,但最简单的是:
insert into Parent (Col1, Col2, ...) values (@Col1, @Col2, ...);
select * from Parent where Id = SCOPE_IDENTITY();
设置完成后,您需要做的就是创建具有Id
的父行,这些行是唯一的(在单个数据集中)但在数据库中是不可能的。负数通常是一个不错的选择。然后,当您将数据集更改保存到数据库时,所有新的父行都将从数据库中获得真正的Id
。
注意:如果您碰巧使用数据库而没有多语句支持且没有存储过程(例如Access),则需要在父表适配器中的RowUpdated
事件上设置事件处理程序。在hanler中,您需要使用select @@IDENTITY
命令获得身份。
一些链接:
答案 1 :(得分:3)
要指出的一切事情。
是的,您肯定需要为两个表分配关系。您可以从xsd编辑器中检查(双击您的xsd文件)。默认情况下,关系设置为“仅关系”,没有任何“更新规则”。通过进入“编辑关系”并选择“仅限外键约束”或“两者都~~~”来编辑此关系。并且需要将“更新规则”设置为Cascade! “删除规则”取决于您。
现在,当您将新的子表行的ID(AutoIncrement)用作新的子表行作为外键时,您必须先将父行添加到表中,然后再使用新的父行ID。
只要使用tableadapter为父表调用Update,关联的子表的新行就会自动具有正确的parentID。
我的简单代码片段:
'--- 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/