2017-08-01 135 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。 –

相關問題