Cascade Delete

We got child-entities, that are removed using CascadeTypeAll, as you can see in below example.

TChild = class;
TParent = class
private
  FModifiable: Boolean;
  [ManyValuedAssociation([TAssociationProp.Lazy], CascadeTypeAllRemoveOrphan, 'FParent')]
  FChild: proxy<TList<TChild>>;
...

TSubChild = class;
TChild = class
private
  FParent: proxy<TParent>;
  [Association([TAssociationProp.Lazy], CascadeTypeAll)]
  FSubChild: proxy<TSubChild>;

  procedure OnDeleting(aArgs: TDeletingArgs);
...

TSubChild = class
private
  [ManyValuedAssociation([TAssociationProp.Lazy], CascadeTypeAllButRemove, 'FSubChild')]
  FParent: proxy<TList<TChild>>; // 1:1 association property returns only TChild 
  
  procedure OnDeleting(aArgs: TDeletingArgs);
...

procedure TChild.OnDeleting(aArgs: TDeletingArgs);
begin
  if Assigned(FParent.Value) and not FParent.Value.Modifiable then
    raise Exception.Create('not modifiable');
end;

procedure TSubChild.OnDeleting(aArgs: TDeletingArgs);
begin
  if Assigned(FParent.Value) and Assigned(FParent.Value.Parent) and not FParent.Value.Parent.Modifiable then
    raise Exception.Create('not modifiable');
end;

So right now, if wie remove an instance of TChild, TSubChild will be removed by Cascade Remove.
TSubChild.OnDeleting will fetch another instance of TChild, because it is already removed from ObjectManager

TObjectManager.InternalRemove:

...
RemoveObjectFromObjectManager(Entity);

CascadeRemove(Entity, BaseEntityType, TAssociationKind.SingleValued, Trash);
...

we could prohibit this second fetch, if RemoveObjectFromObjectManager(Entity); would be done after CascadeRemove of SingleValued Associations.

Prohibit this second fetch is one point, but I do this with this States:
OwnsObjects = True
DeferDestruction = False
CachedUpdates = True

This leads to an exception, if TParent is saved in same batch operation.
This exception occurs, because of RemoveOrphan cascade as follow-up to create a new instance out of TSubChild.OnDeleting...

For now, I could deal with it by removing TSubChild within TChild.OnDeleting, but I think this needs to be fixed...

Oh, I don't think this should be done at this point, 12 years after it's been working like this in Aurelius. There are good reasons why it's before the cascade - which I don't remember all of them right now, of course. :slight_smile:

In the end, it's you who are explicitly fetching the parent, when you call FParent.Value.