質問: 1つまたは複数の子テーブルによって外部キーと呼ばれる親テーブルのID主キーに基づいて親/子関係を持つ複数のテーブルを更新する必要があります。 * 大量のデータがあるため、これらのテーブルをメモリに構築し、C#のSqlBulkCopyを使用してDataSetまたは個々のDataTableのデータベースを更新します。 * 私たちはさらに、複数のスレッド、プロセス、および場合によってはクライアントから、これを並行して実行したいと考えています。 F#のプロトタイプは、34倍のパフォーマンス向上を約束していますが、このコードは親テーブルに既知のIdentity値を強制します。強制されないと、SqlBulkCopyが行を挿入したときにIdentity列が正しく生成さ*れます*が、Identity値はメモリ内のDataTableで更新されません。さらに、たとえそうであったとしても、DataSetが親子関係を正しく修正するかどうかは不明であるため、子テーブルは後で正しい外部キー値で書き込むことができます。 誰もがSqlBulkCopyの更新ID値と、個々のDataTableのFillSchemaにDataAdapterが呼び出されたときに自動的に行われない場合、親子関係を保持および更新するようにDataSetを構成する方法を説明できます。 私が探していない答え: * データベースを読み取って現在の最も高いIdentity値を見つけ、次に各親行を作成するときに手動でインクリメントします。複数のプロセス/クライアントでは機能しません。トランザクションが失敗すると、いくつかのIdentity値がスキップされる可能性があることを理解しています。 * 親行を1度に1つずつ書き出し、Identity値を元に戻します。これは、SqlBulkCopyを使用することで得られた利益の少なくとも一部を無効にします(親ルートよりも多くの子行がありますが、まだ親行がたくさんあります)。 次の答えられない質問に似ています: * 自動生成されたアイデンティティキーを使用してデータセットの親テーブルと子テーブルを更新する方法
回答: まず第一に:SqlBulkCopyはあなたが望むことをすることができません。名前が示すように、それはちょうど "一方通行の通り"です。私は可能な限り迅速にSQL Serverにデータを移動します。生のテキストファイルをテーブルにインポートする古い一括コピーコマンドの.Netバージョンです。したがって、SqlBulkCopyを使用している場合は、ID値を取得する方法はありません。 私は大量のデータ処理を行っており、この問題に何度も直面しています。ソリューションは、アーキテクチャとデータの配布に依存します。ここにいくつかのアイデアがあります: * スレッドごとに1組のターゲット表を作成し、これらの表にインポートします。最後にこれらのテーブルを結合します。これらのほとんどは、TABLENAMEというテーブルから自動的にTABLENAME_THREAD_IDというテーブルを生成する非常に一般的な方法で実装できます。 * IDの生成を完全にデータベースから移動します。たとえば、IDを生成する中央Webサービスを実装します。その場合は、コールごとに1つのIDを生成するのではなく、ID範囲を生成する必要があります。さもなければ、ネットワークオーバーヘッドは通常ボトルネックになります。 * あなたのデータからIDを生成してみてください。可能であれば、あなたの問題はなくなっていたはずです。速くすることはできません。おそらく、後処理ステップでクリーンアップできる文字列IDを使用できますか? もう1つの発言:BulkCopyを使用した場合の因子34の増加は、意見が小さくなるほどです。データを高速に挿入する場合は、データベースが正しく構成されていることを確認してください。