web-dev-qa-db-ja.com

Delphi:TClientDatasetをインメモリデータセットとして使用する

このページ、 によれば、TClientDatasetを実際のデータベースやファイルから完全に独立したメモリ内データセットとして使用することが可能です。データセットのテーブル構造を設定する方法と、実行時にデータをデータセットにロードする方法について説明します。しかし、私がD2009でその指示に従おうとしたとき、ステップ4(table.Open)例外が発生しました。それは指定されたプロバイダーを持っていなかったと述べました。

このページの例の要点は、プロバイダーを必要としないデータセットを構築することです。ページが間違っていますか、それは古くなっていますか、それともどこかにステップがないのですか?そして、ページが間違っている場合、完全に独立したインメモリデータセットを作成するために代わりに何を使用する必要がありますか?私はTJvMemoryDataを使用していますが、可能であれば、データセットがプロジェクトに追加する余分な依存関係の量を減らしたいと思います。

22
Mason Wheeler

実行時にtable.CreateDatasetを使用できます。これがデザイン画面にある場合は、CDSを右クリックして[データセットの作成]をクリックできます。ただし、これを行うには、CDSの列/タイプを指定する必要があります。

22
MikeJ

さらに役立つ場合は、メモリ内のテーブルとして使用されるClientDatasetを作成したコードを次に示します。

procedure TfrmPRMain.ConfigureDataset;
begin
  With cdsMain do begin
    FieldDefs.Add('bDelete', ftBoolean);
    FieldDefs.Add('sSource', ftString, 10);
    FieldDefs.Add('iSection', ftInteger);
    FieldDefs.Add('iOrder', ftInteger);
    FieldDefs.Add('sBranch', ftString, 10);
    FieldDefs.Add('sPulseCode', ftString, 10);
    FieldDefs.Add('sCode', ftString, 10);
    FieldDefs.Add('dtWorkDate', ftDate);
    FieldDefs.Add('iWorkWeek', ftInteger);
    FieldDefs.Add('sName', ftString, 50);
    CreateDataSet;
    LogChanges := False;
    Open;
  end;
end;

あなたは自分のデータ情報を置き換えるだけで行くことができます。ジャック

20
jrodenhi

インストールにMIDAS.DLLを含めるか、uses句にMidasLibを含めることを忘れないでください。そうでない場合、TClientDataSetを使用すると、クライアントのマシンでエラーが発生します。多分それは明白ですが、私は実際にこれを一度忘れました。

8
vrad

table.CreateDataSetを使用できます

7
Tom

このページのコードは、Delphiのどのバージョンでも機能しません。 CreateDataSetの呼び出しにより、データセットはすでにアクティブな状態(「オープン」)になっています。 .CreateDataSet OR .Openを使用する必要があります。両方を使用することはできません。

(ProviderNameプロパティを介して)プロバイダーからデータをフェッチする場合は.Openを使用し、自分でデータセットにデータを入力する場合は.CreateDataSetを使用します。

ところで:ClientDataSetsとその機能に関する詳細なリファレンスについては、優れた CodeGear Developer NetworkのCary Jensenの記事 (最も古いものを最初に読んでください)

6
F.D.Castel

依存関係がなく、高品質で機能が豊富な(もちろん無料です!)インメモリデータセットが必要な場合は、 kbmMemTable を強くお勧めします。 TClientDatasetが行うすべてのことを行い、次にいくつかを行います。

3
Tim Sullivan

どういうわけか、これは私のために働いていません。設計時にCreateDatasetを実行しましたが、それでもアプリケーションがクラッシュします。それはまだ私には不明です。警告が1つあります。こんなことしないで:

XXXClientDataSet.Close;
XXXClientDataSet.Open;

エラーを報告するからです。 Openの代わりに、

xxxClientDataSet.CreateDataset;

私のアプリケーションでは、データをリセットして再度ロードする必要があり、それによって再びエラーメッセージが表示されました。

1
Simon

いくつかのlibreコンポーネントの墓地の石

Delphi 5/Delphi 7の時代には、公開されたプロパティを持つオブジェクト(より正確には、配列またはそれらのコレクション)をデータベースに作成する取り組みがありました。 Torry.netでは、これらはLINQ以前のCollectionDataSetとObject DataSetなどです。しかし、DB-VCLコードはほとんど文書化されておらず、16ビットDelphi 1.0以降のスパゲッティなので、これらは開発されていません。

コールバックベース(イベントベース)のSnap Object Datasetもありますが、それほど古くはありません。ただし、開発者の肩にはIMHOが多すぎます。

TDBF.sf.netテーブルにはメモリ内モードがありましたが、早期に削除されました。 TDBFも死んでいます。

rxLib/JediVCLにはMemoryDatasetがあります。 16ビットのDelphi 1からDelphi 5までは、rxLibターゲットはソースレベルの互換性でしたが、それによってコードが大幅に機能しなくなりました。 JVCLでは、いくつかの注意が払われ、古いコードが削除されましたが、必要以上に些細な使用法よりも必要な場合は、まだ不完全なままです。

最近のリリースではなく、SQLMemoryTableのような無料の個人用DCUコンポーネントもあります。FirebirdEmbedded/SQLiteを使用して、RAMdriveのようなシステム全体のハックを使用せずにメモリ内テーブルを作成できるかどうか疑問です:-)

1
Arioch 'The

私にとって、これはmidas.dllの不一致が原因でした。 MidasLibをメインプログラムのuses句に追加して修正しました(したがって、ライブラリを静的にリンクしています)。詳細はこちら: http://codeverge.com/embarcadero.datasnap/tclientdataset-createdataset-failing-wit/1097715 そしてここ: http://edn.embarcadero.com/article/29297

0
Ludecan

私の好みは、実際にデータセットをXMLとして管理することです。デザイナーツールを使用して基本的な構造を作成し、それをディスクに保存できます。これにより、実行可能ファイルの外で管理したり、リソースとしてコンパイルしたり、バージョン管理で個別に管理したりできます。

この方法で行う場合は、LoadFromFile/StreamおよびSaveバリアントを使用できます。使用方法に応じて、LogChangesとMergeChangeLogを適切に使用することを忘れないでください。

0

これは、最初の投稿でOPによって言及された修正済みの作業コードです。 DBGridに表示されるTClientDatasetからメモリテーブルを取得します。

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DB, DBClient, Grids, DBGrids, StdCtrls, MidasLib;

type
  TForm1 = class(TForm)
    MemTable: TClientDataSet;
    Button1: TButton;
    Button2: TButton;
    DBGrid1: TDBGrid;
    DataSource1: TDataSource;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  i: Word;
begin
  MemTable.DisableControls;
  for i := 1 to 20000 do
  begin
    MemTable.Append;
    MemTable.FieldByName('ID').AsInteger       := i;
    MemTable.FieldByName('Status').AsString    := 'Code'+IntToStr(i);
    MemTable.FieldByName('Created').AsDateTime := Date();
    MemTable.FieldByName('Volume').AsFloat     := Random(10000);
    MemTable.Post;
  end;
  MemTable.EnableControls;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  MemTable.IndexFieldNames := 'Volume';
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  MemTable.FieldDefs.Add('ID',      ftInteger, 0, False);
  MemTable.FieldDefs.Add('Status',  ftString, 10, False);
  MemTable.FieldDefs.Add('Created', ftDate,    0, False);
  MemTable.FieldDefs.Add('Volume',  ftFloat,   0, False);
  MemTable.CreateDataSet;
end;

end.
0
avra