一个人会希望……。这样会起作用(至少在没有计算字段的情况下);
uses
dsintf;
[..]
procedure TForm1.Button1Click(Sender: TObject);
begin
ClientDataSet1.First;
while not ClientDataSet1.Eof do begin
PRecInfo(ClientDataSet1.ActiveBuffer +
ClientDataSet1.RecordSize).Attribute := dsRecNew;
ClientDataSet1.Next;
end;
end;
好吧,它可以工作,但只要没有重新检索数据。即TCustomClientDataSet.GetRecord
重新设置记录属性。我猜这使得 hacky 方法毫无用处。
也许可以尝试绑定一个数据感知控件,看看设置 DataSource 的 DataLink 的 BufferCount 是否会有所帮助。或者,尝试在后代 ClientDataSet 中覆盖 GetRecord。但我怀疑这是否值得努力。
[编辑]
记录属性可以在“AfterScroll”事件中被破解。例如,这将有助于测试 UpdateStatus 以返回“usInserted”的代码。
procedure TForm1.ClientDataSet1AfterScroll(DataSet: TDataSet);
begin
PRecInfo(DataSet.ActiveBuffer + DataSet.RecordSize).Attribute := dsRecNew;
end;
测试是否插入了所有记录
procedure TForm1.Button1Click(Sender: TObject);
begin
ClientDataSet1.First;
while not ClientDataSet1.Eof do begin
if not (ClientDataSet1.UpdateStatus = usInserted) then
raise Exception.Create('The record is not inserted');
ClientDataSet1.Next;
end;
end;
可以派生一个新的 TClientDataSet 来检索始终“插入”的记录。
(类型声明在包含 ClientDataSet 的表单/数据模块之前)
type
TClientDataset = class(dbclient.TClientDataSet)
function GetRecord(Buffer: PChar; GetMode: TGetMode; DoCheck: Boolean):
TGetResult; override;
end;
[..]
implementation
function TClientDataset.GetRecord(Buffer: PChar; GetMode: TGetMode;
DoCheck: Boolean): TGetResult;
begin
Result := inherited GetRecord(Buffer, GetMode, DoCheck);
if Result = grOk then
PRecInfo(Buffer + RecordSize).Attribute := dsRecNew;
end;
现在对于所有记录,UpdateStatus 将返回“usInserted”。
编辑
我终于明白,目的是为所有记录生成插入 SQL。我们不会通过修改 DataSet 的记录属性来实现这一点,ApplyUpdates 只考虑“Delta”,我们可能没有 Delta。可能有不同的方法来实现这一点,下面的示例假设 DataSet 有一个 Provider 并且我们能够在其上放置一个事件处理程序。
type
TForm1 = class(TForm)
[..]
private
procedure DeltaAfterScroll(DataSet: TDataSet);
[..]
implementation
procedure TForm1.DeltaAfterScroll(DataSet: TDataSet);
begin
// The UpdateTree of the Resolver of the Provider will visit each
// record to get the UpdateStatus
PRecInfo(DataSet.ActiveBuffer + DataSet.RecordSize).Attribute := dsRecNew;
end;
type
TAccessCCDS = class(TCustomClientDataSet);
procedure TForm1.Button1Click(Sender: TObject);
var
Count: Integer;
begin
ClientDataSet1.MergeChangeLog;
// Since there's no "Delta", ApplyUpdates will return immediately.
// Hence, we'll force an update by calling DoApplyUpdates, bypassing the
// ChangeCount test, and update with the "Data".
// Reconcilation is left out for simplicity.
TAccessCCDS(ClientDataSet1).DoApplyUpdates(ClientDataSet1.Data, 0, Count);
end;
procedure TForm1.DataSetProvider1UpdateData(Sender: TObject;
DataSet: TCustomClientDataSet);
begin
// Will be called once when ApplyUpdates is called.
TAccessCCDS(DataSet).AfterScroll := DeltaAfterScroll;
end;