Delphi: utiliser TClientDataset comme un ensemble de données en mémoire

Selon cette page il est possible d'utiliser TClientDataset comme un dataset en mémoire, totalement indépendant de bases de données ou fichiers. Il décrit comment configurer la structure de la table de l'ensemble de données et comment y charger des données à l'exécution. Mais quand j'ai essayé de suivre ses instructions dans D2009, étape 4 (table.Open) a soulevé une exception. Il a dit qu'il n'avait pas un fournisseur spécifié.

le point entier de l'exemple sur cette page est de construire un ensemble de données qui n'a pas besoin d'un prestataire. La page est mal, est-il obsolète, ou ai-je raté une étape quelque part? Et si la page est erronée, que dois-je utiliser à la place pour créer un ensemble de données complètement indépendant en mémoire? J'ai été en utilisant TJvMemoryData, mais si possible j'aimerais réduire la quantité supplémentaire de dépendances que mon dataset ajoute dans mon projet.

19
demandé sur Fabrizio 2008-11-08 20:23:18

11 réponses

à l'exécution, vous pouvez utiliser table.CreateDataset ou si c'est sur une surface de dessin, vous pouvez cliquer droit sur le CD et cliquez sur créer un dataset. Vous devez avoir des colonnes/types spécifiés pour les CDS avant de pouvoir le faire.

20
répondu MikeJ 2018-06-15 08:54:34

si cela aide plus loin, voici un morceau de code où j'ai créé un ClientDataset qui est utilisé comme une table en mémoire:

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;

Vous pouvez simplement remplacer vos propres informations de données et aller. Jack

20
répondu jrodenhi 2008-11-08 20:15:33

N'oubliez pas D'inclure MIDAS.DLL dans votre installation ou tout simplement inclure MidasLib dans la clause d'utilisation. Autrement en utilisant TClientDataSet déclenchera une erreur sur la machine du client. C'est peut-être évident, mais j'ai oublié cette fois.

8
répondu vrad 2018-06-15 08:56:33

Vous pouvez utiliser table.CreateDataSet

7
répondu Tom 2018-06-15 08:55:52

le code de cette page ne fonctionne dans aucune version Delphi. Un appel à CreateDataSet met déjà l'ensemble de données en état actif ("ouvert"). Tu devrais l'utiliser .CreateDataSet OR .Ouvrir. Pas les deux.

Utilisation .Ouvrez lorsque vous voulez récupérer des données d'un fournisseur (via la propriété ProviderName) et .CreateDataSet quand vous voulez peupler l'ensemble de données par vous-même.

BTW: pour une référence en profondeur sur les données client et ses fonctionnalités, jetez un oeil sur excellent Cary Jensen articles sur CodeGear Developer Network (lire les plus anciennes, d'abord)

5
répondu F.D.Castel 2008-11-09 07:57:05

si vous souhaitez un sans dépendance, de haute qualité, et riche en fonctionnalités (sans mentionner gratuit!) dataset en mémoire, je recommande fortement kbmMemTable. Fait tout TClientDataset et puis certains.

3
répondu Tim Sullivan 2018-06-15 08:57:15

Cimetière pierres ci-dessous pour quelques libre composants

dans les temps de Delphi 5 / Delphi 7 Il y avait des initiatives pour faire n'importe quel objet avec des propriétés publiées (plus précisément - tableau ou une certaine collection de ceux-ci) dans une base de données. Sur Torry.net il S'agit de CollectionDataSet et D'un ensemble de données D'objets Des années avant LINQ. Mais depuis DB-VCL code est peu documenté et est spaghetti depuis 16-bit Delphi 1.0 - ceux-ci n'ont pas de développement.

Il y a aussi ensemble de données Snap Object basé sur le rappel (basé sur les événements), pas si désuet. Bien qu'il laisse trop D'IMHO sur les épaules des développeurs.

TDBF.sf.net table avait le mode mémoire, mais a été retiré tôt. TDBF est mort aussi.

rxLib/JediVCL has MemoryDataset. Bien que la cible de rxLib était compatible au niveau de la source depuis 16-bit Delphi 1 jusqu'à Delphi 5. Qui a paralysé le code beaucoup. Dans JVCL il a eu une certaine attention et la suppression du code de vieillissement, mais est toujours à moitié cuit lorsque nécessaire plus profond que négligeable d'utilisation.

Il y a aussi des composants DCU gratuits pour le personnel comme SQLMemoryTable, mais pas pour les versions récentes. Je me demande si Firebird Embedded / SQLite pourrait être utilisé pour créer une table en mémoire sans utiliser des hacks à l'échelle du système comme RAMdrive : -)

1
répondu Arioch 'The 2011-10-11 20:34:51

pour une raison que ça ne fonctionne pas pour moi. J'ai effectuer CreateDataset dans le temps de conception, mais il se bloque encore application. Qui est encore inconnu pour moi. Un avertissement. DO NOT DO THIS:

XXXClientDataSet.Close;
XXXClientDataSet.Open;

parce qu'il signalera une erreur. Au lieu de Open, utilisez

xxxClientDataSet.CreateDataset;

dans mon application, j'avais besoin de réinitialiser les données et de les charger à nouveau, et cela a encore causé un message d'erreur.

1
répondu Fabrizio 2018-06-15 08:56:57

Ma préférence est de gérer l'ensemble de données en XML. Vous pouvez utiliser les outils du concepteur pour créer la structure de base et ensuite la sauvegarder sur le disque. Cela lui permet d'être géré à l'extérieur de l'exécutable compilé en tant que ressource, ou gérés séparément dans le contrôle de version.

lorsque vous le faites de cette façon, vous pouvez utiliser LoadFromFile/Stream et les variantes de sauvegarde. N'oubliez pas d'utiliser correctement les LogChanges et MergeChangeLog en fonction de votre usage.

0
répondu Ryan VanIderstine 2009-05-26 02:04:16

Pour moi, cela a été causé par un midas.incompatibilité dll. Je l'ai corrigé en ajoutant MidasLib aux programmes principaux utilise la clause (liant ainsi statiquement la bibliothèque). Plus d'infos ici: http://codeverge.com/embarcadero.datasnap/tclientdataset-createdataset-failing-wit/1097715 et ici: http://edn.embarcadero.com/article/29297

0
répondu Ludecan 2014-05-16 23:24:39

il s'agit d'un code de travail corrigé mentionné par OP dans le premier message. Vous obtenez une table de mémoire d'un TClientDataset affiché dans DBGrid.

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
répondu avra 2018-06-15 08:57:36