8

親行が投稿されているかどうかに応じて、いくつかの子行をメモリに投稿してから、条件付きで投稿するか、基になるSQLデータベースに投稿しないようにします。完全なORMは必要ありませんが、おそらくこれだけです。

  1. ユーザーが[医師の追加]をクリックします。[医師の追加]ダイアログボックスが開きます。
  2. [医師の追加]ダイアログで[OK]をクリックする前に、ユーザーはメモリにのみ保持される1人以上の患者を追加します。
  3. ユーザーは、[ドクターの追加]ウィンドウで[OK]をクリックします。これで、すべての患者と新しい医師が保管されます。
  4. ユーザーがドクターウィンドウで[キャンセル]をクリックすると、すべてのドクターと患者の情報が破棄されます。

精神的には、delphiデータ対応コントロールとTADOQueryまたはその他のADOオブジェクトを使用して上記を実行する方法を想像してみてください。これを行うための非ADO固有の方法がある場合、私もそれに興味があります。現在のアプリケーションでMS-SQL ServerとADOを使用しているため、ADOを公開しているだけです。

そのため、私が短期間働いていた以前の雇用主にはTMasterDetail、上記をADOレコードセットに追加するために特別に作成されたというクラスがありました。それは時々機能しました、そして他の時にはそれはいくつかの本当に興味深くそして修正するのが難しい方法で失敗しました。

VCL、またはこの手法を実行するための堅牢な方法を備えたサードパーティコンポーネントに組み込まれているものはありますか?そうでない場合、私が上で話していることはORMを必要としますか?ORMは多くの人から「悪い」と見なされていると思いましたが、上記は100万のアプリケーションで発生する可能性のある非常に自然なUIパターンです。非ADO非Delphi-db-datasetスタイルの作業を使用している場合、上記は、作成する可能性のあるほとんどすべての永続層で問題にはなりませんが、ID値を使用してリンクする主キーを持つデータベースの場合はマスター行と詳細行が画像に入り込み、事態は複雑になります。

更新:この場合、トランザクションはほとんど理想的ではありません。(コミット/ロールバックは、私の目的には粗すぎるメカニズムです。)

4

1 に答える 1

3

2つの別々の質問をする:

  1. 更新をキャッシュするにはどうすればよいですか?
  2. 関連するテーブルの更新を同時にコミットするにはどうすればよいですか。

キャッシュされた更新は、さまざまな方法で実行できます。どちらが最適かは、特定の状況によって異なります。

ADOバッチアップデート

ADOを使用してデータにアクセスしていることをすでに述べているので、これは妥当なオプションです。データセットを開く前に、LockTypeをltBatchOptimisticに設定し、CursorTypeをctKeySetまたはctStaticに設定する必要があります。次に、コミットする準備ができたら、TADOCustomDataset.UpdateBatchを呼び出します。

注:これを利用するには、基になるOLEDBプロバイダーがバッチ更新をサポートしている必要があります。SQLServerのプロバイダーはこれを完全にサポートしています。

データを永続化するときにマスターと詳細の関係を強制する方法は、両方のデータセットでUpdateBatchを順番に呼び出す以外にありません。

Parent.UpdateBatch;
Child.UpdateBatch;

クライアントデータセット

データキャッシングはの存在の主な理由の1つでありTClientDataset、マスター/詳細関係の同期はまったく難しくありません。

これを実現するには、通常どおり2つのデータセットコンポーネントでマスター/詳細関係を定義します(この場合はADOQueryまたはADOTable)。次に、単一のプロバイダーを作成し、それをマスターデータセットに接続します。シングル をプロバイダーに接続TClientDatasetすれば完了です。TClientDatset詳細データセットをネストされたデータセットフィールドとして解釈します。このフィールドには、他のデータセットと同じように、データ対応コントロールにアクセスしてバインドできます。

これが設定されたら、電話をかけるだけTClientDataset.ApplyUpdatesで、クライアントデータセットがマスター/詳細データの更新を正しく順序付けします。

ORM

ORMについて言えることはたくさんあります。StackOverflowの回答に収まらないので、簡単に説明します。

ORMは最近悪いラップを得ています。一部の専門家は、アンチパターンのラベルを付けるところまで行っています。個人的にはこれは少し不公平だと思います。オブジェクトリレーショナルマッピングは、正しく解決するのが非常に難しい問題です。ORMは、リレーショナルテーブルとオブジェクトのインスタンスの間でデータを転送する際の複雑さの多くを抽象化することで支援を試みます。しかし、ソフトウェア開発の他のすべてと同様に、特効薬はなく、ORMも例外ではありません。

多くのビジネスルールのない単純なデータ入力アプリケーションの場合、ORMはおそらくやり過ぎです。しかし、アプリケーションがますます複雑になるにつれて、ORMはより魅力的に見え始めます。

ほとんどの場合、独自のORMを使用するのではなく、サードパーティのORMを使用することをお勧めします。要件に完全に適合するカスタムORMを作成することは良い考えのように思え、単純なマッピングを開始するのは簡単ですが、親子関係、継承、キャッシュ、キャッシュの無効化などの問題がすぐに発生し始めます(これを知っていると信じてください)経験から)。サードパーティのORMはすでにこれらの問題に遭遇しており、それらを解決するために膨大な量のリソースを費やしています。

多くのORMでは、コードの複雑さと構成の複雑さを交換します。それらのほとんどは、慣習や方針に目を向けることによって定型文の構成を減らすために積極的に取り組んでいます。各テーブルの列を各クラスの対応するプロパティIdにマップするのではなく、すべての主キーに名前を付ける場合は、この規則についてORMに通知するだけで、すべてのテーブルとクラスが規則に従うことを認識していると見なされます。適用されない特定の場合にのみ、規則をオーバーライドする必要があります。私はDelphiのすべてのORMに精通しているわけではないので、どれがこれをサポートし、どれがサポートしないかはわかりません。IdId

いずれにせよ、アプリケーションアーキテクチャを設計して、使用するORMフレームワーク(または、さらに言えば、任意のフレームワーク)の決定を可能な限り延期できるようにする必要があります。

于 2012-06-28T17:43:00.640 に答える