TClientDataSet作为内存数据集-是否可以在内存中应用更新而不将数据保存到数据库中?

4
默认情况下,TClientDataSet会跟踪数据集中的所有更改(包括插入、更新和删除)。有没有一种方法可以告诉数据集接受当前的更改(比如使用insert/post进行一系列插入操作)而不需要实际调用数据库来保存任何东西?
我想到的一个办法是使用TDataSetProvider并实现BeforeUpdateRecord事件并将Applied参数设置为true。我不喜欢这里有两件事情。我必须添加两个对象(TDataSetProvider和TSQLQuery对象),然后ApplyUpdates会启动一个事务。有没有更简单的方法?
如果在TClientDataSet上不设置ProviderName,则ApplyUpdates将失败。
谢谢

在插入之前将LogChanges设置为false,或者调用MergeChangeLog。否则我没有理解... - Sertac Akyuz
@SertacAkyuz:就是这样。请回答,以便我可以接受您的答案作为解决方案。 - boggy
@Sertac:看起来你比我更快地回答了这个问题。如果你发布一个包含那些信息的答案,我会删除我的回答。(我看到了这个问题和唯一的答案,但在发布之前没有阅读任何评论。答案应该是你的。) - Ken White
可能是Delphi - applying Delta to a TClientDataSet的重复问题。 - Sir Rufo
@Ken - 好的,谢谢。其实在回答之前你不必关注评论。 - Sertac Akyuz
3个回答

5
你可以在修改数据集之前将 LogChanges 设置为 false。或者,如果在任何阶段需要更改日志,可以调用 MergeChangeLog 来合并更新。

1
请注意,有一个错误(至少在D2006中仍存在)可能会给您带来巨大的头痛:如果LogChanges为False,则某些过滤功能无法正常工作:即使记录的值不符合给定的过滤条件,记录仍可能留在过滤的数据集中。请参见此单元测试:
  procedure TestCDS.TestLogChanges;
  var CDS: TClientDataset;
  begin
     CDS := TClientDataset.Create(NIL);
     try
        CDS.FieldDefs.Add('MyStringField', ftString, 20 );
        CDS.CreateDataSet;
        try
           CDS.LogChanges := False;
           CDS.Filter := 'MyStringField is null';
           CDS.Filtered := True;
           Check( CDS.RecordCount= 0);
           CDS.Insert;
           CDS.Post;
           Check( CDS.RecordCount= 1);
           CDS.Edit;
           CDS.FieldByName('MyStringField').AsString := 'Text';
           CDS.Post;
           Check( CDS.RecordCount= 0, 'Recordcount is not 0 after changing value!');
        finally
           CDS.Close;
        end;
     finally
        CDS.Free;
     end;
  end;

这里也要看一下,显然这是一个旧的错误:http://www.delphigroups.info/2/f0/463155.html


0

我是这样使用它的。我从数据库中加载数据,然后将数据发送到FastReports实例或PDF表单或Excel电子表格中。这使我能够使用一个进程来生成所有不同类型的输出。虽然我设置它已经有一段时间了,但我认为我是按照你描述的方式设置的。


抱歉,我可能没有理解您的意思。听起来Sertac已经给了您所需的东西。希望他能回来并将他的回复作为答案。 - jrodenhi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接