簡體   English   中英

加載現有數據時將新字段添加到FDMemTable

[英]Adding a new Field to FDMemTable when loading an existing data

我正在使用TFDMemTable ,我創建了一個數據集並用數據填充了我的表,然后使用FDMemTable.saveToFile保存了我的數據。
現在這是一個問題,我如何才能向已保存的數據添加新Field ,並用默認值填充所有記錄?
我嘗試將新Field添加到FDMemTable ,然后加載信息,希望它會自動使用它的FieldName和每個空白字段填充新字段,但出現錯誤:`--------- ------------------

調試器異常通知

項目Project1.exe引發異常類EDatabaseError,並顯示消息“未找到字段'Episode'”。

中斷繼續幫助

`
我怎樣才能解決這個問題 ? 是否可以為現有數據添加具有默認值的新字段?
這是一個測試用例:

// here is a simple example, i have a few fields
FDMemTable1.FieldDefs.Add('ID', ftInteger, 0, false);
FDMemTable1.FieldDefs.Add('name', ftString, 30, false);
FDMemTable1.FieldDefs.Add('QualityID', ftInteger, 0, false);

FDMemTable1.CreateDataSet;

// i fill the the table with some value
FDMemTable1.Open;
FDMemTable1.AppendRecord([1, 'Movie1', 1]);
FDMemTable1.AppendRecord([2, 'Movie2', 2]);
FDMemTable1.AppendRecord([3, 'Movie3', 1]);

// after seeing the value on the grid, i push a button and save the table as XML
FDMemTable1.saveToFile('Data.xml');

// now after closing the program and running it again, i want to load the data with a new FieldDef Called Episode with a default value 0
// the table is connected to cxGrid, and the moment i try to load, i get the error i mentioned.

FDMemTable1.FieldDefs.Add('ID', ftInteger, 0, false);
FDMemTable1.FieldDefs.Add('name', ftString, 30, false);
// this line is NEW
FDMemTable1.FieldDefs.Add('Episode', ftInteger, 0, false);
FDMemTable1.FieldDefs.Add('QualityID', ftInteger, 0, false);

FDMemTable1.CreateDataSet;

// i try to load but i get an error
FDMemTable1.loadFromFile('Data.xml');

更新1(基於維多利亞的答案):

//All the codes below are executed after the code at the top, after the loadFromFile.
  FDMemTable1.ResourceOptions.StoreItems := FDMemTable1.ResourceOptions.StoreItems + [siMeta];
  FDMemTable1.Close;

  //i tried putting FDMemTable1 as the owner but when i try the line "FDMemTable1.Fields.add" i get an Duplicate error!
  // and when i try putting nil, i get access violation ! so i tried putting the owner someother random table and it fixed the problem
  fieldDefs := TFieldDefs.Create(someRandomFDMemTable);
  fieldDefs.Add('Episodes', ftString, 30, false);

  FDMemTable1.Fields.Add(fieldDefs.Items[0].CreateField(FDMemTable1));
  FDMemTable1.Open;

如您所見,我有兩個問題,
1-我在添加新字段時遇到問題! 在出現錯誤的地方,我首先嘗試使用TFieldDef而不是TFieldDefs但是我無法使其正常工作。
2-所有列均為空並且網格上沒有數據的事實。
當我嘗試強制解決問題1時,就會出現問題2。

下面的代碼對我在Delphi Seattle中的工作正常。 它與您緊密相關,但有一些細微變化(請參閱注釋)和一項重要補充。

關鍵是,如果您仔細觀察FDMemTable1.loadFromFile ,它實際上會清除FieldDefs / Fields,那么首先要重新設置它們沒有太多的意義,因此添加的Episode字段將被從加載中省略數據集。

為了避免這種情況,我所做的添加工作是使用臨時TFDMemTable,將XML文件加載到其中,然后使用CopyDataSet將其內容復制到FDMemTable1。 FDMemTable1會在此過程中保留添加的Episode字段,當然,您可以添加代碼以在調用CopyDataSet設置Episode字段數據。

procedure TForm1.AddFieldTest;
var
  DataFN : String;
  TempMemTable : TFDMemTable;
begin
  // Added, to avoid relative path for data file name
  DataFN := ExtractFilePath(Application.ExeName) + 'Data.Xml';

  FDMemTable1.FieldDefs.Add('ID', ftInteger, 0, false);
  FDMemTable1.FieldDefs.Add('name', ftString, 30, false);
  FDMemTable1.FieldDefs.Add('QualityID', ftInteger, 0, false);

  FDMemTable1.CreateDataSet;

  // i fill the the table with some value
  FDMemTable1.Open;
  FDMemTable1.AppendRecord([1, 'Movie1', 1]);
  FDMemTable1.AppendRecord([2, 'Movie2', 2]);
  FDMemTable1.AppendRecord([3, 'Movie3', 1]);

  // after seeing the value on the grid, i push a button and save the table as XML
  FDMemTable1.saveToFile(DataFN);

  // Added, close the dataset and clear the FieldDefs
  // Without the FieldDefs.Clear call, your code produces a "Duplicate field ID" error 
  FDMemTable1.Close;
  FDMemTable1.FieldDefs.Clear;

  // now after closing the program and running it again, i want to load the data with a new FieldDef Called Episode with a default value 0
  // the table is connected to cxGrid, and the moment i try to load, i get the error i mentioned.

  FDMemTable1.FieldDefs.Add('ID', ftInteger, 0, false);
  FDMemTable1.FieldDefs.Add('name', ftString, 30, false);
  // this line is NEW
  FDMemTable1.FieldDefs.Add('Episode', ftInteger, 0, false);
  FDMemTable1.FieldDefs.Add('QualityID', ftInteger, 0, false);

  FDMemTable1.CreateDataSet;

  // check the FieldCount and existence of the Episode field
  Caption := IntToStr(FDMemTable1.FieldCount);
  Assert(FDMemTable1.FindField('Episode') <> Nil);

  //  Create a temporary TFDMemTable
  TempMemTable := TFDMemTable.Create(Nil);
  try
    //  load the data into the temporary TFDMemTable
    TempMemTable.loadFromFile(DataFN);
    //  copy the data from the temporary TFDMemTable into FDMemTable1
    FDMemTable1.CopyDataSet(TempMemTable, [coAppend]);

  // check the FieldCount and existence of the Episode field
    Caption := IntToStr(FDMemTable1.FieldCount);
    Assert(FDMemTable1.FindField('Episode') <> Nil);
  finally
    TempMemTable.Free;
  end;
end;

添加一個字段(未字段定義)加載從文件中的數據集之后(包括在假設siMeta StoreItems的財產ResourceOptions您的TFDMemTable )。 請注意,將字段添加到字段集合時必須關閉數據集。

因此,從文件加載后立即關閉數據集,添加字段並再次打開它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM