Recursive Deletes...

Posts   
 
    
pilotboba
User
Posts: 434
Joined: 05-Aug-2005
# Posted on: 18-Jan-2006 18:02:10   

Ok,

I searched and I didn't see much about this.

It looks to me that if I want to delete and Entity, that has related child entity, I have two options.

  1. Implicitly delete the children of the entity using DeleteMulti() first.

  2. Set up cascade deletes in the database RI.

I'm curious why LLBLGen doesn't do the cascade deletes?

Now, that said, is there a way using Adapter that I can code this so I don't have to do it imperivly each time.

For example, the common Customers have Orders scenerio. Is there somewhere in an event OnDelete or BeforeDelete of the Customer entity I can tell it to delete all it's orders?

The idea here would be to code the BL/DAL so that the UI programmer doesn't need to know the database structure. I want the UI to be able to delete the customer and have all the children deleted automatically.

Thanks, BOb

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39613
Joined: 17-Aug-2003
# Posted on: 18-Jan-2006 20:52:54   

cascading deletes aren't always possible (multiple paths from one entity to another cause sqlserver to not accept a cascading delete setting on an FK for example).

Furthermore, cascading deletes with a filter and the filter matches several entities, is only possible with a temptable, as the child entities have to be deleted first, but if the filter is on teh child entities, the parents cant be deleted because you don't know which ones to delete as the children are already gone.

Frans Bouma | Lead developer LLBLGen Pro
pilotboba
User
Posts: 434
Joined: 05-Aug-2005
# Posted on: 20-Jan-2006 23:26:55   

Otis wrote:

cascading deletes aren't always possible (multiple paths from one entity to another cause sqlserver to not accept a cascading delete setting on an FK for example).

Furthermore, cascading deletes with a filter and the filter matches several entities, is only possible with a temptable, as the child entities have to be deleted first, but if the filter is on teh child entities, the parents cant be deleted because you don't know which ones to delete as the children are already gone.

So, how do you recommend deleting an Entity, that has a child that has a child?

For example, delete an Invoice that has InvoiceLines that has GLTransactions?

BOb

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39613
Joined: 17-Aug-2003
# Posted on: 21-Jan-2006 11:37:30   

in a single transaction, delete gltransactions directly, then invoicelines, then invoice. Or define the cascade on the FK in the DB, IF the db accepts that cascade.

Frans Bouma | Lead developer LLBLGen Pro
mario.muja avatar
mario.muja
User
Posts: 37
Joined: 03-May-2005
# Posted on: 28-Feb-2006 10:28:18   

I understand that there are cases where cascade deletes are not possible. However, if no filtering is involved and the database does not accept the cascade or does not support such a feature, then it would be a great feature of LLBLGen to cascade automatically.

This feature should be configurable, so that I can decide, if a cascade delete is allowed for an entity or not (as declarative as the cascade delete checkbox of SQL Server).

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39613
Joined: 17-Aug-2003
# Posted on: 28-Feb-2006 11:52:25   

THe problem is that without loading all data involved in the complete graph into memory, cascade deletes will fail in some occasions and it's unpredicatable when that will be (as it depends on the graph of objects in question). A RDBMS can do it because it knows the data involved.

Frans Bouma | Lead developer LLBLGen Pro
Posts: 254
Joined: 16-Nov-2006
# Posted on: 03-Mar-2007 21:34:37   

Can you elloborate further on why this wouldn't be possible to write into the framework?

If LLBLGen knows about the foreign keys it can surely work out how the entities relate to each other and therefore know the order of entities to remove first e.g. in this example delete the invoice lines before the invoice.

You can probably guess that I'm trying to write similar code right now simple_smile

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39613
Joined: 17-Aug-2003
# Posted on: 04-Mar-2007 11:24:44   

MattAdamson wrote:

Can you elloborate further on why this wouldn't be possible to write into the framework?

If LLBLGen knows about the foreign keys it can surely work out how the entities relate to each other and therefore know the order of entities to remove first e.g. in this example delete the invoice lines before the invoice.

That's not always possible. If you have 2 or more paths from entity A to entity B, it can lead to inproper deletes. This is also the reason why SqlServer sometimes doesn't allow you to enable CASCADE delete on an FK. To quote from the Bol:

The series of cascading referential actions triggered by a single DELETE or UPDATE must form a tree containing no circular references. No table can appear more than once in the list of all cascading referential actions that result from the DELETE or UPDATE. The tree of cascading referential actions must not have more than one path to any given table. Any branch of the tree is terminated when it encounters a table for which NO ACTION has been specified or is the default.

LLBLGen Pro doesn't use a cached mapping model in-memory, it uses a distributed model, where entities know who they are and the system asks them what to do with them, but that's it. This also implies that the mapping information drives the code, not the underlying db model. this means that if you hide a relation, it's not used by the entities, but it IS there in the db.

To determine which entities to delete first, without having these entities in memory requires the complete db model in memory + it requires subqueries per level, and a graph can become widespread, leading to a lot of deletes and it then becomes important in which order the deletes take place which isn't really possible to specify in a proper way (as you would need to specify that for every PK entity type).

When all entities would be in memory, you could sort the graph in-memory and persist changes.

Because of this, we decided not to build it in. One advantage of not having a mapping file with mapping info is that the code itself contains all information. One could use attributes but then adapter would be difficult. One other advantage is that you can decide per situation what to do: set FK's to null or remove related entities.

You can probably guess that I'm trying to write similar code right now simple_smile

Utilize the feature to delete entities directly. For example, if you look at the code of HnD, where a forum is deleted for example, it simply removes all info in the right order.

Some say this is a leaky abstraction, as it leaks the referential integrity into the code, however I find that a bit silly: your entities do have references as well, which means that they thus have a 'depending - dependent' relationship, no matter how hard one tries to deny that. To be able to remove an entity on which others depend on, it's key to remove / reset these first, be it in your own code or be it in the db, because if you don't your data in-memory will be in an undefined state during the actions.

We've always been pretty careful with deletes: they're never automatic: you have to tell the code what to delete.

Frans Bouma | Lead developer LLBLGen Pro