TClientDataSet OnNewRecord与AfterInsert

时间:2017-03-21 09:56:08

标签: c++builder tclientdataset

我的问题是将记录插入到firebird数据库的表中。该表非常简单 - 它只有2列:

CREATE TABLE myTable
(
    COL_ID CHAR(36) NOT NULL CONSTRAINT PK_COL_ID PRIMARY KEY USING INDEX IX_COL_ID, 
    COL_ACRONYM VARCHAR(255)
);

在我的应用程序(c ++ Builder XE10)中,我有以下星座:

  • 连接到
  • 的TDataSource
  • 连接到
  • 的TClientDataSet
  • 连接到
  • 的TDataSetProvider
  • 连接到
  • 的TFDTable
  • 连接到
  • 的FDConnection
  • Firebird数据库

该应用程序执行以下操作:

  1. 使用TClientDataSet.Append();
  2. 插入新行
  3. 编辑新插入的记录。
  4. 使用TClientDataSet.ApplyUpdates(-1);
  5. 保存此记录

    只要我手动执行第二步或在AfterInsert事件中编辑数据,一切都按预期工作:

    __fastcall TFormMain::TFormMain(TComponent* Owner)
        : TForm(Owner)
    {
        ClientDataSet1->Active = true;
    }
    
    UnicodeString TFormMain::GenerateGuid( void )
    {
        // ...some fancy code creating and returning a GUID...
    }
    
    void __fastcall TFormMain::ButtonAppendClick(TObject *Sender)
    {
        ClientDataSet1->Append();
    }
    
    void __fastcall TFormMain::ButtonSaveClick(TObject *Sender)
    {
        ClientDataSet1->ApplyUpdates(-1);
    }
    
    void __fastcall TFormMain::ClientDataSet1AfterInsert(TDataSet *DataSet)
    {
        DataSet->FieldByName( "COL_ID" )->AsString = GenerateGuid();
        DataSet->FieldByName( "COL_ACRONYM" )->AsString = "Whatever: this works!";
    }
    

    这很好......到目前为止......

    由于其他一些变化,我决定将数据的自动创建移动到TClientDataSet的NewRecord事件中:

    void __fastcall TFormMain::ClientDataSet1NewRecord(TDataSet *DataSet)
    {
        DataSet->FieldByName( "COL_ID" )->AsString = GenerateGuid();
        DataSet->FieldByName( "COL_ACRONYM" )->AsString = "Not too good...";
    }
    

    第一时间看起来不错,因为GUI上的数据库控件已经填充了正确的数据。但是只要我点击“保存”按钮,数据就会消失,新记录也没有存储到数据库中 - 好像我取消了这个过程。

    其次我注意到,如果我在执行ApplyUpdates()之前手动更改其中一列,那么就会存储记录。

    所以我只是为自动发布添加了以下行:

    void __fastcall TFormMain::ClientDataSet1NewRecord(TDataSet *DataSet)
    {
        DataSet->FieldByName( "COL_ID" )->AsString = GenerateGuid();
        DataSet->FieldByName( "COL_ACRONYM" )->AsString = "Not too good...";
        DataSet->Post();
    }
    

    这个小小的改变确实起了作用。 我现在的问题是:为什么? AfterInsert会自动发布新记录吗? 在NewRecord事件之后它们保持不变时,Append()添加的记录会自动取消吗?

    问候和感谢

    赫维希

1 个答案:

答案 0 :(得分:1)

据我所知,TDataSet的{​​{1}}和OnNewRecord事件处理程序之间的区别是:

  • AfterInsert中的编辑字段值将将记录标记为已修改
  • OnNewRecord中的编辑字段值会将记录标记为已修改

我想这是问题的原因