TClientDataSet used as in-memory dataset - is it possible to apply the updates in-memory without saving the data to a database?

StackOverflow https://stackoverflow.com/questions/22213481

By default, the TClientDataSet tracks all the changes made in the DataSet (inserts, updates, deletes). Is there a way to tell the dataset to accept the current changes (after a series of inserts using insert/post, let's say) without actually calling the database to save anything?

One idea that I thought of was to use a TDataSetProvider and implement the BeforeUpdateRecord event and set the Applied parameter to true. I don't like two things about this. I have to add two more objects (TDataSetProvider and the TSQLQuery object) and ApplyUpdates starts a transaction. Is there a simpler way?

If I don't set the ProviderName on the TClientDataSet, ApplyUpdates fails.

Thanks

有帮助吗?

解决方案

You can set LogChanges to false before modifying the dataset. Alternatively, if you need the change log at any stage, you can call MergeChangeLog to incorporate updates.

其他提示

Be aware that there is a bug (at least still in D2006) that may cause you a great headache: If LogChanges is False, some of the filter functionality is not working correctly: Records may remain inside a filtered dataset even if their values do not match the given filter criteria.

See this unit test:

  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;

Also have a look here, it obviously is an older bug: http://www.delphigroups.info/2/f0/463155.html

I use it that way. I load it with data from a database and then send the data to a FastReports instance or to PDF forms or an Excel spreadsheet. It makes it possible for me to use one process to produce all my different kinds of output. It has been a while since I set it up but I think I set it up the way you are describing.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top