Подтвердить что ты не робот

Delphi: использование TClientDataset в качестве набора данных в памяти

В соответствии с этой страницей можно использовать TClientDataset как набор данных в памяти, полностью независимый от любых фактических баз данных или файлов. В нем описывается, как настроить структуру таблицы набора данных и как загружать данные в нее во время выполнения. Но когда я попытался выполнить его инструкции в D2009, шаг 4 (table.Open) вызвал исключение. Он сказал, что у него не указана провайдер.

Вся точка примера на этой странице заключается в создании набора данных, который не нужен провайдеру. Является ли страница неправильной, она устарела или я чего-то не хватает? И если страница неверна, что мне нужно использовать вместо этого, чтобы создать полностью независимый набор данных в памяти? Я использую TJvMemoryData, но, если возможно, я хотел бы уменьшить количество дополнительных зависимостей, которые добавляет мой набор данных в мой проект.

4b9b3361

Ответ 1

во время выполнения вы можете использовать table.CreateDataset, или если это на поверхности дизайна, вы можете щелкнуть правой кнопкой мыши на CDS и щелкнуть по созданию набора данных. вам нужно иметь определенные столбцы/типы для CDS, прежде чем вы сможете это сделать.

Ответ 2

Если это помогает, вот фрагмент кода, в котором я создал 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;

Вы можете просто заменить свою собственную информацию и уйти. Джек

Ответ 3

Использовать таблицу .CreateDataSet

Ответ 4

Не забудьте включить MIDAS.DLL в вашу установку или просто включить предложение MidasLib в uses. В противном случае использование TClientDataSet вызовет ошибку на клиентской машине. Может быть, это очевидно, но я действительно забыл об этом однажды.

Ответ 5

Код с этой страницы не работает в ЛЮБОЙ версии Delphi. Вызов CreateDataSet уже ставит набор данных в активное состояние ( "открыт" ). Вы должны использовать .CreateDataSet ИЛИ .Open. Не оба.

Используйте.Открыть, когда вы хотите получать данные от Провайдера (через свойство ProviderName) и .CreateDataSet, когда вы хотите заполнить набор данных самостоятельно.

BTW: Для получения подробной справки о ClientDataSets и ее функциях обратите внимание на отличные статьи статьи Cary Jensen в сети разработчиков CodeGear (читайте самые старые сначала)

Ответ 6

Если вы хотите использовать бесплатный набор данных (не говоря уже о бесплатном!) в базе данных без зависимостей, без каких-либо ограничений, я настоятельно рекомендую kbmMemTable. Делает ли все TClientDataset, а затем некоторые.

Ответ 7

по какой-то причине это не работает для меня. Я выполняю CreateDataset во время разработки, но он все еще сбой приложения. Это пока неизвестно. Одно предупреждение. НЕ ДЕЛАЙТЕ ЭТО:

XXXClientDataSet.Close;
XXXClientDataSet.Open;

потому что он сообщит об ошибке. Вместо Open используйте

xxxClientDataSet.CreateDataset;

В моем приложении мне понадобилось reset данные и загрузить его снова, и это снова вызвало сообщение об ошибке.

Ответ 8

Камни кладбищ ниже для некоторых компонентов libre

Во времена Delphi 5/Delphi 7 были инициативы по созданию в базе данных любого объекта с опубликованными свойствами (точнее - массивом или некоторой коллекцией).  На Torry.net это CollectionDataSet и Object DataSet Годы до LINQ и т.д. Но поскольку код DB-VCL мало документирован и является спагетти с 16-разрядного Delphi 1.0 - у них нет разработки.

Существует также набор данных Snap Object, основанный на обратном вызове (на основе событий), не столь устаревший. Хотя он оставляет слишком много ИМХО на плечах разработчиков.

В таблице TDBF.sf.net был включен режим памяти, но был удален. TDBF также мертв.

rxLib/JediVCL имеет MemoryDataset. Хотя целью rxLib была совместимость на уровне исходного кода с 16-разрядного Delphi 1 до Delphi 5. Это сильно исказило код. В JVCL у него было некоторое внимание и удаление кода старения, но он по-прежнему является наполовину испеченным при необходимости более глубоким, чем тривиальное использование.

Кроме того, существуют также бесплатные персональные компоненты DCU, такие как SQLMemoryTable, но не для последних выпусков. Интересно, можно ли использовать Firebird Embedded/SQLite для создания таблицы в памяти без использования общесистемных хаков, таких как RAMdrive: -)

Ответ 9

Мое предпочтение - фактически управлять набором данных как XML. Вы можете использовать инструменты конструктора для создания базовой структуры, а затем сохранить ее на диск. Это позволяет управлять им за пределами исполняемого файла, скомпилированным в качестве ресурса или отдельно управляемым в управлении версиями.

При выполнении этого способа вы можете использовать LoadFromFile/Stream и варианты Save. Не забудьте правильно использовать LogChanges и MergeChangeLog в зависимости от вашего использования.

Ответ 10

Это скорректированный рабочий код, упомянутый OP в первом сообщении. Вы получаете таблицу памяти из TClientDataset, показанной в 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.

Ответ 11

Для меня это было вызвано несоответствием midas.dll. Я исправил это, добавив MidasLib к основному предложению использования программы (таким образом, связывая библиотеку статически). Подробнее здесь: http://codeverge.com/embarcadero.datasnap/tclientdataset-createdataset-failing-wit/1097715 и здесь: http://edn.embarcadero.com/article/29297