3

各 CDS の DataSetProvider とのマスター/詳細関係に 2 つの ClientDataSet を使用します。マスターと詳細の関係に対してメモリ内フィルタリングを行うため、詳細にはネストされた CDS を使用しません。

私が抱えている問題は、基礎となるデータベース (firebird) に変更を適用する必要がある場合です。詳細 INSERT の場合は最初にマスターを適用する必要があり、詳細 DELETE の場合は最初に詳細を適用する必要があります (データベースのマスターと詳細の関係に違反することなく)。ここまでは順調ですね。しかし、詳細 CDS に INSERT と DELETE が混在している場合はどうすればよいでしょうか? その後、マスター CDS の前後に適用できません。

ネストされた CDS を使用せずに、このような状況をどのように処理できますか?

4

3 に答える 3

2

通常、1つのマスターレコードを挿入/更新してから、詳細(挿入、更新、削除)を操作します。問題を解決する1つの方法は、操作全体をトランザクションに配置し(変更を加える前にトランザクションを開始)、マスターレコード(単一レコード)を挿入/更新し、実行しMasterCDS.ApplyUpdates、詳細レコードを処理しDetailCDS.ApplyUpdates、最後にトランザクション全体をコミットまたはロールバックすることです。 。CDSはマスター/詳細関係にあるため、編集されるとすぐにDetailCDSレコードが「表示」され、に入るとすぐに主キー値が取得されます。このようにして、参照整合性(外部キー制約)を維持し、で何でも実行できます。MasterCDSPostApplyUpdatesMasterCDSDetailCDS

さらに、両方にイベントがありTClientDataSetTDataSetProviderプロセス全体を(ほぼ)完全に制御できるため、利用可能なすべてのイベントを詳しく調べてください。

注:これを私の記憶から説明しているので、いくつかの詳細について間違っているかもしれませんが、アイデアは重要です。少し実験してみると、解決策が見つかります。

于 2011-11-23T22:50:04.320 に答える
0

個別のデータセットプロバイダーを使用すると、各DSPの更新が個別のトランザクションで行われることがわかりました(少なくともInterbaseでは)。私はこれには関心がありませんでしたが、アプリケーションではすべてのデータセットの一貫性を保つ必要があるかもしれません。

于 2011-11-26T10:12:36.853 に答える
0

マスターを適用してからディテールを適用します。

マスター レコードを削除する場合は、 BeforeApplyUpdatesイベントをオーバーライドして詳細レコードをカスケード削除します。

詳細を削除すると、BeforeApplyUpdates を再度オーバーライドする必要があります。マスター レコードが見つからない場合は、わざわざ削除を実行しないでください。

カスタム更新コマンドを使用して、詳細レコードの削除を「スキップ」できます。これを行う唯一の理由は、datasnap が SQL コマンド自体を生成し、影響を受ける行 = 0 のために失敗するのを防ぐことです。おそらく、次のようなものを使用します。

IF EXISTS (SELECT * FROM dbo.ParentTable WHERE ParentKey = @ParentKey)
BEGIN
  DECLARE @rowcount INT
  DELETE
    FROM dbo.ChildTable
    WHERE ChildKey = @ChildKey
  SET @rowcount = @@ROWCOUNT
  IF @rowcount <> 1
  BEGIN
    RAISERROR('Record not found.(%d)', 15, 1, @rowcount) WITH SETERROR
  END
END

次に、BeforeUpdateRecord イベントでこのコマンドを呼び出します

case UpdateStatus of
  ukDelete:
    begin
      sqlDeleteChild.Parameters.ParamByName('@ChildKey').Value := DeltaDS.FieldByName('ChildKey').OldValue;
      sqlDeleteChild.Parameters.ParamByName('@ParentKey').Value := DeltaDS.FieldByName('ParentKey').OldValue;
      sqlDeleteChild.Execute;
    end;
  ...
end;
Applied := true;
于 2011-11-24T01:14:58.357 に答える