4

編集: DataSetProvider にはこのプロジェクトに必要な機能がないように思われるため、データを ClientDataSet にロードするためのカスタム クラスを実装します。

DB に接続されている TMSQuery からデータを取得し、DataSetProvider を使用してそのデータの一部を ClientDataSet に入力しようとしています。

私の問題は、ClientDataSet に入る前に、このデータの一部を変更する必要があることです。ClientDataSet には、生の DB データと一致しない永続フィールドがあります。DB から ClientDataSet のメモ フィールドに文字列を取得することさえできません。

ClientDataSet はデータ層の一部であるため、DB から ClientDataSet へのデータをフィールドごとに適合させる必要があります (ほとんどはそのまま通過できますが、多くはルーティングや変換が必要になります)。

誰もこれを経験していますか?

4

3 に答える 3

2

TDataSetProvider.BeforeUpdateRecordイベントを探しています。このイベントのイベントハンドラーを作成すると、データがデータベースに適用される方法を手動で制御できます。

このようなもの

procedure TDataModule1.DataSetProvider1BeforeUpdateRecord(Sender: TObject; SourceDS: TDataSet; DeltaDS: TCustomClientDataSet; UpdateKind: TUpdateKind; var Applied: Boolean);
begin
  { Set applied to tell DataSnap that you have applied this record yourself }
  Applied := True;

  case UpdateKind of
    ukModify:
      begin
        Table1.Edit;
        { set the values of the fields something like this }
        if not VarIsEmpty(DeltaDS.FieldByName('NewValue')) then
          Table1['SomeField'] := DeltaDS.FieldByName('SomeField').NewValue;
        Table1.Post;
    end;

    ukInsert:
      begin
        Table1.Insert;
        { set the values of the fields }
        Table1['SomeField'] := DeltaDS['SomeField']
        Table1.Post;
      end;

    ukDelete:
      if Table1.Locate('PrimaryKeyField', DeltaDS['PrimaryKeyField'], []) then
        Table1.Delete;
  end; // case
end;
于 2010-03-30T22:49:35.977 に答える
1

TDataSetProvider.OnGetDataイベントを実装することにより、ClientDataSetに送られるデータを変更できます。

procedure TDataModule1.DataSetProvider1GetData(Sender: TObject; DataSet: TCustomClientDataSet);
begin
  DataSet.First;
  while not DataSet.Eof do begin
    DataSet.Edit;
    DataSet['Surname'] := UpperCase(DataSet['Surname']);
    DataSet.Post;
    DataSet.Next;
  end; // while
end;

ClientDataSetから更新を適用する場合は、TDataSetProvider.OnUpdateDataイベントを使用できます。OnGetDataイベントと同様に、単一のレコードではなく、データセット全体を操作しています。

procedure TDataModule1.DataSetProvider1UpdateData(Sender: TObject; DataSet: TCustomClientDataSet);
begin
  DataSet.First;
  while not DataSet.Eof do begin
    DataSet.Edit;
    DataSet['Surname'] := LowerCase(DataSet['Surname']);
    DataSet.Post;
    DataSet.Next;
  end; // while
end;

このOnUpdateDataイベントは、OnBeforeUpdateRecordイベントの前に呼び出されます。また、OnGetDataイベントとOnUpdateDataイベントはデータセット全体で動作し、OnBeforeUpdateRecordは変更されたレコードごとに1回呼び出されます。

于 2010-03-31T20:41:21.097 に答える
0

データベース スキーマと正確に一致しないデータを持つ ClientDataSet が必要な場合は、必要な形式でデータを返す TQuery コンポーネントのクエリを記述します。次に、TQuery コンポーネントに対して独自の個別の削除、挿入、更新、および更新クエリを作成します。

または、データベースにビューを作成し、そのビューを TQuery コンポーネントで使用することもできます。

データベースから独立したカスタム ClientDataSet が必要な場合、必要なのはインメモリ データセットです。メモリ内データセット コンポーネントがない場合は、Google で「TClientDataSet as in-memory dataset」を検索してください。ただし、最終的には、基本的に美化されたリスト ビュー コンポーネントになります。もちろん、メモリ内データセットの OnUpdateRecord にフックして、実際のデータセットをいつ更新するかを知ることができます。

于 2010-03-30T21:18:34.113 に答える