Local and remote data adapters performing differently when applying detail deltas

Ok spent quite a while tracking this down. I’ll try to make it as simple as possible.

As per this topic from a couple of years ago…

…I’m using this mechanism to retrieve a large hierarchy of data with a single “up front” round trip to the server to populate all data, rather than retrieving data for sub-details as their parents are navigated.

This all works fine but it does necessitate that RemoteFetchEnabled is set to False on all the detail tables, otherwise it attempts to re-fetch data from the server, despite it already being present.

I’ve hit a problem whereby, if i use this method to retrieve the hierarchy, then make changes to one or more records in one or more detail tables (i.e. NOT the top-level parent), then when I call ApplyUpdates on the top-level parent table, nothing is done. No error is reported but no changes are applied to the database at all.

Further investigation revealed that this behaviour is only evident when using a TDALocalDataAdapter. When using a TDARemoteDataAdapter, it works correctly!

Tracing through the code in both cases, I’ve discovered the following:

  1. The TDABaseDataAdapter.InternalApplyUpdatesAndThrowFailures calls InternalApplyUpdates_DetectTablesForUpdate, passing the single top-level parent table in aTables.

  2. Within TDABaseDataAdapter.InternalApplyUpdates_DetectTablesForUpdate, as the CheckTable nested function returns False, due to RemoteFetchEnabled being set to False, no detail tables are added. The function thus returns aDestList and aDestListwithDetails both with just the single top-level parent table. If RemoteFetchEnabled were set to True then the entire table hierarchy would be returned by this function but, in this case, it isn’t.

  3. TDABaseDataAdapter.InternalApplyUpdatesAndThrowFailures then calls InternalApplyUpdates. Both the lTables and lTablesWithDetails lists passed contain only the single top-level table returned above.

  4. When a remote data adapter is in use, TDARemoteDataAdapter.InternalApplyUpdates is called. This calls UpdateDataCall.Execute() which does no work at all. No updates are applied to the tables for the detail tables with deltas.

  5. When a local data adapter is in use however, TDALocalDataAdapter.InternalApplyUpdates is called. This adds the single top-level parent table to the aList array and then calls ServiceInstance.UpdateData. Despite only the top-level parent table being passed, the deltas on the detail tables are correctly applied and the database is updated.

My first question is obviously why these two functions are behaving differently. Surely the local and remote data adapters should perform identically?

Second question is how I can get around this. The root of the problem appears to be that TDABaseDataAdapter.InternalApplyUpdates_DetectTablesForUpdate isn’t compiling a list of all detail tables due to RemoteFetchEnabled being False. Unfortunately it has to be False on the detail tables for my bulk retrieval system to operate correctly.

I notice that the nested CheckTable function does have a code path based around the moIncludeDeltaIntoMasterCall but I’m unsure exactly what this option does or what the implications of setting it would be. Would this potentially solve my issue?

Hope you can provide some insight.

List item


I’ll review why we have difference in LDA and RDA.

In this case, I can recommend to perform ApplyUpdates as

  RDA.ApplyUpdates([mastertable, detail1,... subdetail1,...]);
//  LDA.ApplyUpdates([mastertable, detail1,... subdetail1,...]);

this will include all tables with deltas regardless from RemoteFetchEnabled property.

1 Like

Thanks, logged as bugs://83753

Thanks I’ll give that a try

bugs://83753 got closed with status fixed.

1 Like