首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >TFDMemTable过滤后数据丢失/清除

TFDMemTable过滤后数据丢失/清除
EN

Stack Overflow用户
提问于 2017-08-02 03:43:34
回答 2查看 2.4K关注 0票数 0

我已经创建了一个具有以下结构的FDMemTable:

代码语言:javascript
复制
Cds_NaMenu := TFDMemTable.Create(nil);
Cds_NaMenu.FieldDefs.Add('ID', ftInteger);
Cds_NaMenu.FieldDefs.Add('MN_TELA_CODIGO', ftInteger);
Cds_NaMenu.FieldDefs.Add('MN_MENU_PESQUISA', ftString, 500);
Cds_NaMenu.FieldDefs.Add('DISPONIBILIDADE', ftInteger);
Cds_NaMenu.IndexDefs.Add('Ordem', 'MN_TELA_CODIGO', []);
Cds_NaMenu.CreateDataSet;
Cds_NaMenu.LogChanges := False;
Cds_NaMenu.IndexName := 'Ordem';

我将数据放在TFDMemTable中,如下所示:

代码语言:javascript
复制
Cds_NaMenu.Append;
Cds_NaMenu.FieldByName('DISPONIBILIDADE').AsInteger := 1;
Cds_NaMenu.Post;

好吧..。当将filtered属性设置为True并将其设置回False时,就会出现问题。RecordCount属性变为0;在中未找到数据,即使我使用saveToFile过程也是如此。显然,数据丢失了。

代码语言:javascript
复制
_recCount := Cds_NaMenu.RecordCount; // Result = 867;
Cds_NaMenu.Filter := 'DISPONIBILIDADE=1 AND MN_MENU_PESQUISA like ' + QuotedStr('%' + sTexto + '%');
Cds_NaMenu.Filtered := True;
_recCount := Cds_NaMenu.RecordCount; // Result = 0;
Cds_NaMenu.Filtered := False;
Cds_NaMenu.Filter := '';
_recCount := Cds_NaMenu.RecordCount; // Result = 0;

PS:使用ClientDataSet,这段代码可以很好地工作

EN

回答 2

Stack Overflow用户

发布于 2017-08-02 09:27:42

如果您使用的是纯内存表,那么通过属性查询记录计数应该不会有任何问题。您可能希望在具有像‘%%’这样的筛选器值时,筛选视图中包含空和空值记录,但事实并非如此。当有这样的数据集时:

代码语言:javascript
复制
ID | Value
1  | NULL
2  | ''
3  | 'Some text'

然后像这样应用滤镜:

代码语言:javascript
复制
var
  S: string;
begin
  S := '';
  FDMemTable.Filtered := False;
  FDMemTable.Filter := 'Value LIKE ' + QuotedStr('%' + S + '%');
  FDMemTable.Filtered := True;
  { ← FDMemTable.RecordCount should be 1 here for the above dataset }
end;

视图中不应包含empty和NULL value记录。这里有一个简短的证明:

代码语言:javascript
复制
var
  S: string;
  MemTable: TFDMemTable;
begin
  MemTable := TFDMemTable.Create(nil);
  try
    MemTable.FieldDefs.Add('ID', ftInteger);
    MemTable.FieldDefs.Add('Value', ftString, 500);
    MemTable.IndexDefs.Add('PK_ID', 'ID', [ixPrimary]);
    MemTable.CreateDataSet;

    MemTable.AppendRecord([1, NULL]);
    MemTable.AppendRecord([2, '']);
    MemTable.AppendRecord([3, 'Some text']);

    S := '';
    MemTable.Filtered := False;
    MemTable.Filter := 'Value LIKE ' + QuotedStr('%' + S + '%');

    ShowMessage(Format('Total count: %d', [MemTable.RecordCount])); { ← should be 3 }
    MemTable.Filtered := True;
    ShowMessage(Format('Filtered count: %d', [MemTable.RecordCount])); { ← should be 1 }
    MemTable.Filtered := False;
    ShowMessage(Format('Total count: %d', [MemTable.RecordCount])); { ← should be 3 }
  finally
    MemTable.Free;
  end;
end;
票数 1
EN

Stack Overflow用户

发布于 2017-08-02 06:22:51

我认为这只是一个小的FD怪癖。下面的代码按照预期工作,并将Cds_NaMenu声明为TFDMemTable (不过,如果您可以删除Cds_以避免混淆,那就更好了)。

我认为,关键的区别在于清除过滤器后对.Locate的调用。我把它放在那里的原因是因为它会导致数据集滚动,我想,结果是重新计算它的RecordCount。可能任何其他导致滚动的操作都会有相同的效果,即使是MoveBy(0) -尝试一下。

代码语言:javascript
复制
procedure TForm1.FormCreate(Sender: TObject);
var
  _recCount : Integer;
  ID : Integer;
  sTexto : String;
begin
  sTexto := 'xxx';  // added

  Cds_NaMenu.FieldDefs.Add('ID', ftInteger);
  Cds_NaMenu.FieldDefs.Add('MN_TELA_CODIGO', ftInteger);
  Cds_NaMenu.FieldDefs.Add('MN_MENU_PESQUISA', ftString, 500);
  Cds_NaMenu.FieldDefs.Add('DISPONIBILIDADE', ftInteger);
  Cds_NaMenu.IndexDefs.Add('Ordem', 'MN_TELA_CODIGO', []);
  Cds_NaMenu.CreateDataSet;
  Cds_NaMenu.LogChanges := False;
  Cds_NaMenu.IndexName := 'Ordem';


  Cds_NaMenu.Append;
  Cds_NaMenu.FieldByName('ID').AsInteger := 666;  // added
  Cds_NaMenu.FieldByName('DISPONIBILIDADE').AsInteger := 1;
  Cds_NaMenu.Post;


  _recCount := Cds_NaMenu.RecordCount; // Result = 1

  ID := Cds_NaMenu.FieldByName('ID').AsInteger;  // added

  Cds_NaMenu.Filter := 'DISPONIBILIDADE=1 AND MN_MENU_PESQUISA like ' + QuotedStr('%' + sTexto + '%');
  Cds_NaMenu.Filtered := True;
  _recCount := Cds_NaMenu.RecordCount; // Result = 0;
  Cds_NaMenu.Filtered := False;
  Cds_NaMenu.Filter := '';

  // Now force the dataset to scroll
  if Cds_NaMenu.Locate('ID', ID, []) then;  // added
  _recCount := Cds_NaMenu.RecordCount; // Result = 1;
  Caption := IntToStr(_recCount);  // added
end;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45446427

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档