Clear extra DA parameters for detail table in master-detail link

How do you create a master detail link where extra dataadapter parameters are also cleared

We have a master-detail relation on 2 TDADataTable objects.

They are linked using

DetailTable.MasterMappingMode := mmWhere;
DetailTable.DetailFields := DetailFields;
DetailTable.MasterFields := MasterFields;

and optionaly DetailTable.MasterParamsMappings.Text :=DetailTable.DetailFields +‘=’ +

This works in our application but when we used shared dataadapters a detail fetch sometimes fails because a previous request to the dataadapter set some DA parameter.

At some point another DATable executes a remote fetch but it sets a getdatacall parameter

roParam:=DARemoteDataAdapter.GetDataCall.FindParam(‘ExtraWhere’);
if roParam<>nil then
roParam.Value:=newValue;

However the detail DA table does not have this parameter (and definately does not want to add some extra where clause)

How can we clear GetDataCall parameters for all the detail table remote fetches

Note: If we don’t share data adapters between DATables we do not have the issue but the code is very slow.

Each LoadSchema takes 0.2 seconds and we have many places where DATable’s (dataadapters) get created

FYI: One approach might be to have an explicit DetailGetDataCall where nothing sets parameters?

Woud that work? Can the method be specified for detail links?

Hi,

note: MasterParamsMappings is ignored if mmWhere mode is used.

Why are you using ExtraWhere with mmWhere mode? you can just add limitation to DynWhere.Expression instead.

Hi, The ExtraWhere is used for a totaly unrelated DA Table

The reason we use it is

Hi,

do you mean that server’s call is executed slowly?
you can call LoadSchema only once.

  • create own TDARemoteDataAdapter descendant
  • override function GetSchema: TDAClientSchema; override; method
  • in this method you can return already downloaded schema

Hi,

I also thought about caching the schemas but didn’t know how.

How do you propose to cache?

A simple global singleton TDAClientSchema which starts as nil and once set can always use the cached singleton?

I can consider the schema as an immutable object? As long as the server hasn’t changed the returned schema will be identical? The data adapter itself does not modify/lock/…

Hi,

you can grab schema at loading client-side.(RDA.Schema. ofc, RDA.CacheSchema = True)
later, you return it for other RDA:

function TMyDARemoteDataAdapter.GetSchema: TDAClientSchema;
begin
   Result := masterRDA.Schema;
end; 

by other hand, you can just assign it like

procedure TMyDARemoteDataAdapter.AssignSchema(Source: TDAClientSchema);
begin
   fSchema.Assign(Source);
end; 

Hy Evgeny,

Looking at your code I was wondering about ownership.

The GetSchema function returns a reference to a single instance

The AssignSchema makes a copy by value of some schema.

Whathappens when TMyDARemoteDataAdapter gets destroyed?

Maybe in the first case TMyDARemoteDataAdapter.fSchema remains some instance which does not get used by anything (but gets destroyed by the owner)?

Hi,

nothing.
RDA stores schema in fSchema variable:

    fSchema: TDAClientSchema;
    function GetSchema: TDAClientSchema; override;
    property Schema: TDAClientSchema read GetSchema;
...

function TDABaseDataAdapter.GetSchema: TDAClientSchema;
begin
  Result := ReadSchema(not fCacheSchema);
end;

function TDABaseDataAdapter.ReadSchema(aForceReRead: Boolean): TDAClientSchema;
begin
...
  Result := fSchema;
end;

new GetSchema method doesn’t touch this variable and just replaces value of schema on-fly:

function TMyDARemoteDataAdapter.GetSchema: TDAClientSchema;
begin
   Result := masterRDA.Schema;
end;