嵌套数据集中的Clientdataset'索引未找到'错误

时间:2018-03-27 21:33:31

标签: delphi tclientdataset

我试图通过使用clone cursor来使用indexdef来查找记录,从而在clientdataset中找到记录的子集。在下面的示例中,我创建了一个按钮来实现克隆创建。该代码适用于名为cdsData的clientdataset。但是,如果我将cdsData嵌套在另一个数据集(cdsMaster)中,那么按钮代码将无法找到indexDef。

Form:(包括显示数据源和clientdatasets的两个clientdatasets。在下面的第一个单元示例中省略dsMaster& cdsMAster)

object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 289
  ClientWidth = 554
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 13
  object Button1: TButton
    Left = 32
    Top = 24
    Width = 75
    Height = 25
    Caption = 'Clone'
    TabOrder = 0
    OnClick = Button1Click
  end
  object dsMaster: TDataSource
    DataSet = cdsMaster
    Left = 56
    Top = 80
  end
  object cdsMaster: TClientDataSet
    Aggregates = <>
    Params = <>
    Left = 56
    Top = 144
  end
  object dsData: TDataSource
    DataSet = cdsData
    Left = 152
    Top = 88
  end
  object cdsData: TClientDataSet
    Aggregates = <>
    Params = <>
    Left = 152
    Top = 144
  end
end

成功的cdsData单位:

unit IndexFindTest;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Data.DB, Datasnap.DBClient;

type
  TForm1 = class(TForm)
    dsData: TDataSource;
    cdsData: TClientDataSet;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  Disp, Lbl : string;
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  Clone: TClientDataset;
begin
  Clone := TClientDataset.Create(nil);
  try
    Clone.CloneCursor(cdsData,false);
    cdsData.IndexDefs.Update;
    clone.IndexName := cdsData.IndexDefs.find ('Lbl').Name;
    //..added code to select a range of records using the IndexDef
  finally
    clone.free;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  disp := 'Item 1';
  lbl := 'a';
   with TStringField.Create(Self) do begin
    Name := 'MstrDisplays';
    FieldKind := fkData;
    FieldName := 'Displays';
    Size := 10;
    DataSet := cdsData;
  end;

   with TStringField.Create(Self) do begin
    Name := 'MstrLabel';
    FieldKind := fkData;
    FieldName := 'Label';
    Size := 10;
    DataSet := cdsData;
  end;


  with cdsData.IndexDefs.AddIndexDef do begin
    Name := 'Lbl';
    Fields := 'Displays;Label';
    Options := [ixCaseInsensitive];
  end;
  cdsData.CreateDataSet;
end;

end.

失败的嵌套版本:

unit IndexFindTest2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Data.DB, Datasnap.DBClient;

type
  TForm1 = class(TForm)
    dsMaster: TDataSource;
    cdsMaster: TClientDataSet;
    Button1: TButton;
    dsData: TDataSource;
    cdsData: TClientDataSet;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  Disp, Lbl : string;
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  Clone: TClientDataset;
begin
  Clone := TClientDataset.Create(nil);
  try
    Clone.CloneCursor(cdsData,false);
    cdsData.IndexDefs.Update;

    //Error generated in next line
    clone.IndexName := cdsData.IndexDefs.find ('Lbl').Name;

    //..added code to select a range of records using the IndexDef    
  finally
    clone.free;
  end;
end;


procedure TForm1.FormCreate(Sender: TObject);
begin
  disp := 'Item 1';
  lbl := 'a';
   with TStringField.Create(Self) do begin
    Name := 'MstrTitle';
    FieldKind := fkData;
    FieldName := 'Title';
    Size := 10;
    DataSet := cdsMaster;
  end;
  with TDataSetField.Create(Self) do
  begin
    Name := 'MstrDisplay';
    FieldName := 'Displays';
    DataSet := cdsMaster;
  end;

  cdsData.DataSetField := TDataSetField(cdsMaster.FieldByName('Displays'));
  with TStringField.Create(Self) do begin
    Name := 'ClientNested';
    FieldKind := fkData;
    FieldName := 'Notes';
    Size := 10;
    DataSet := cdsData;
  end;

  with TStringField.Create(Self) do begin
    Name := 'kntLabel';
    FieldKind := fkData;
    FieldName := 'Label';
    Size := 10;
    DataSet := cdsData;
  end;

  cdsData.IndexDefs.Update;
  with cdsData.IndexDefs.AddIndexDef do begin
    Name := 'Lbl';
    Fields := 'Notes;Label';
    Options := [ixCaseInsensitive];
  end;
  cdsMaster.CreateDataSet;
end;
end.

运行第二个程序时,我收到错误

  

cdsData:找不到索引'Lbl'。

我可以在两个程序之间识别的唯一区别是cdsData嵌套在第二个版本中。我在CaryJensen的深度Delphi中找到了一个注释:clientDatasets第2版(第128页)声明错误可能发生并且可以使用更新修复,但无论在哪个序列中我应用更新,它都不适用于这种情况。 / p>

任何人都可以解释这个问题吗?嵌套数据集是否有其他步骤?

0 个答案:

没有答案