2017-08-01 224 views
0

我创建了一个FDMemTable用以下结构之后清除数据:TFDMemTable丢失/过滤

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这样的:

Cds_NaMenu.Append; 
Cds_NaMenu.FieldByName('DISPONIBILIDADE').AsInteger := 1; 
Cds_NaMenu.Post; 

嗯......这个问题ocurrs当将过滤的属性设置为True并返回False。 RecordCount属性变为0;没有找到数据,即使我使用saveToFile过程。原来数据丢失了。

_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的,这个代码工作完全

+1

代码依赖数据集的RecordCounts返回有意义的值是要求麻烦。除此之外,不同的数据集类型以不同的方式表现,就像你发现的那样。听起来像你的实际问题是一个X/Y的问题。 – MartynA

回答

0

我认为这只是一个小FD怪癖。下面的代码按预期工作,Cds_NaMenu声明为TFDMemTable(尽管如果您可以放弃Cds_以避免混淆,它会很好)。

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

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

如果它设置了一个纯内存表,那么就不需要“滚动获取”,因为一切都在客户端,所描述的问题不应该发生。 – Victoria

+0

@Victoria,当然我认识到应该不需要滚动,但遇到了很多情况,而不仅仅是使用FireDAC,像这样的问题可以通过强制滚动来解决,即使它不执行任何操作,比如' MoveBy(0)'。顺便说一句,我正确地猜测,如果我去帮助|关于和做Alt-Team欺骗不热衷于Firebird的人的名字滚动到视图中; =)? – MartynA

+0

刚应用了一个过滤器,并且不得不强制滚动,读起来会不会更容易,而且只需要调用First? – Frazz

1

如果您使用的是纯内存表,那么通过RecordCount属性查询记录数应该不会有任何问题。也许你期望有NULL过滤视图中包含的值记录具有过滤器时值LIKE'%%',但事实并非如此。当具有数据集是这样的:像这样

ID | Value 
1 | NULL 
2 | '' 
3 | 'Some text' 

和应用过滤器:

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; 

NULL值的记录不应该包括在视图中。这是一个简短的证明:

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; 
+0

我完全同意你的看法! 问题是:在Filtered设置为False后,.RecordCount不会回到3。 –