自動生成された ID キーを使用してデータセットの親テーブルと子テーブルを更新するにはどうすればよいですか?
質問
VB アプリケーションで ADO.NET データセットを使用しています。1 つの親テーブルと多数の子テーブルを持つ型付きデータセットがあります。親テーブルにデータを挿入するときにアイデンティティ キーを生成し、すべての子テーブルのデータを同じキー (Foregin キーとして) で更新したいと考えています。
最後に、データベース(SQL Server08)のデータセットを更新したいと思います。
上記のことは、まず親テーブルをデータベースに直接挿入し、Identity 列を取得してから子テーブルに使用することで可能になります。
しかし、私はこれを自動操作として行いたいです(データコンテキストで主キーと外部キーを処理するLINQ to SQLのように)。
親テーブルと子テーブルの自動生成列を処理するデータセットでそのようなことは可能ですか?
ありがとう、
ABB
正しい解決策はありません
他のヒント
これはより明白であり、何も調整せずに機能するはずだと思います。しかし、それでも、それは非常に簡単です。
ソリューションには 2 つの部分があります。
作成する
DataRelation
子テーブルと親テーブルの間で更新をカスケードするように設定します。そうすれば、親 ID が変更されるたびに、すべての子が更新されます。Dim rel = ds.Relations.Add(parentTab.Columns("Id"), childTab.Columns("ParentId")) rel.ChildKeyConstraint.UpdateRule = Rule.Cascade
データセットの挿入および更新コマンドは双方向です。バインドされた出力パラメーターまたは返されたデータ行がある場合、それらは更新の原因となるデータセット行の更新に使用されます。
これは、この特定の問題に最も役立ちます。自動生成列をアプリケーションに戻します。ID とは別に、これはたとえばタイムスタンプ列である可能性があります。しかし、アイデンティティが最も役立ちます。
必要なのは、ID を返すように挿入コマンドを設定することだけです。これを行うにはいくつかの方法があります。たとえば、次のとおりです。
a) 出力パラメータを指定したストアド プロシージャを使用する。これは、「実際の」データベースの中で最も移植性の高い方法です。
b) 複数の SQL ステートメントを使用し、最後の SQL ステートメントは挿入された行を返します。これは私の知る限り SQL Server に特有のものですが、最も単純なものは次のとおりです。
insert into Parent (Col1, Col2, ...) values (@Col1, @Col2, ...); select * from Parent where Id = SCOPE_IDENTITY();
これを設定したら、次のようにして親行を作成するだけです。 Id
(単一のデータセット内で) 一意であるが、データベース内では不可能です。通常は、負の数値が適切な選択です。次に、データセットの変更をデータベースに保存すると、すべての新しい親行が実際になります。 Id
データベースから。
注記:複数のステートメントのサポートやストアド プロシージャを使用せずにデータベースを操作する場合 (例:Access)、イベント ハンドラーをセットアップする必要があります。 RowUpdated
親テーブルアダプターのイベント。ハンラーではアイデンティティを取得する必要があります select @@IDENTITY
指示。
いくつかのリンク:
注意すべき点がいくつかあります。
はい、両方のテーブルにリレーションを割り当てる必要があります。xsdエディター(xsdファイルをダブルクリック)から確認できます。デフォルトでは、リレーションは「更新ルール」を持たない「リレーションのみ」として設定されます。この関係を編集するには、「関係の編集」に移動し、「外部キー制約のみ」または「両方~~~」を選択します。そして、「更新ルール」をカスケードとして設定する必要があります。「削除ルール」はあなた次第です。
新しい親テーブルの行の 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)
お役に立てれば幸いです!
そして、あなたはあなたがあなたのモデルを更新することができるようチャイルズに割り当てられたIDを取得し、IDを取得し、まだデータセットを使用したくない場合は: https://danielwertheim.wordpress.com/2010/10/ 24 / C-バッチアイデンティティ・インサート/ の