OnDelete not called when deleted from DeleteMulti

Posts   
 
    
gabrielk avatar
gabrielk
User
Posts: 231
Joined: 01-Feb-2005
# Posted on: 09-Nov-2007 13:11:46   

Hi,

I've got some code to prevent the deletion of an entity in certain cases in an override of the OnDelete of the entity.

Example:


        protected override void OnDelete()
        {
            if (this.OrderItem.Count > 0)
            {
                 // Throw error delete is not alllowed
            }

            base.OnDelete();
        }

I also perform some deletion of child controls in ondeletee like:


            this.OrderItem.DeleteMultiManyToOne(this);

the problem now is that when I delete an entity with a direct call to .Delete() on the entity the OnDelete code gets executed (I debugged it), but when the Entity is deleted from a parent entity with the DeleteMultiManyToOne function the code is not excuted :S ?!

The entity is deleted from the database but it's OnDelete code was never executed. Any suggestions where to start digging for this problem?

I looked in the source code of LLBL and see it's a Delete that's called in the DeleteMulti() but for some reason it doesn't reach the OnDelete code of my Entity.

It's selfservice, 2 class scenario, // Code is generated using LLBLGen Pro version: 2.0.0.0 Designer 15th of July 2007.

Thanks, Gab.

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 09-Nov-2007 14:59:42   

Why don't you use OnValidateEntitiyBeforeDelete?

gabrielk avatar
gabrielk
User
Posts: 231
Joined: 01-Feb-2005
# Posted on: 09-Nov-2007 15:20:06   

I didn't know about that event, I am used to OnDelete.

I've added the code to your suggested method too, in an override.

But also that doesn't work...

Scenario: I delete an order, and everything below it should be cascade (if I am right) deleted. I have arranged this temporarily in the OnDelete untill I have a generic solution in our framework. The OnDelete of Order gets hit, it does the DeleteMultiMany (the OrderGarmentActionGroups are deleted from the DB) but the methods in the OrderGarmentActionGroupEntity are not executed.

First this gets hit in the OrderEntity:


        protected override void OnDelete()
        {
            this.OrderGarmentActionGroupCollection.DeleteMultiManyToOne(this);
            base.OnDelete();        
        }

In the OrderGarmentActionGroupEntity the following code is present and NONE of the 3 methods are hit during debug & none of the are executed.


        public override bool Delete(IPredicate deleteRestriction)
        {
            return base.Delete(deleteRestriction);
        }

        protected override void OnValidateEntityBeforeDelete()
        {
            if (this.OrderItemClothingCollection.Count > 0)
            {
                throw new Exception("Entity can not be deleted because of it having childeren.");
            }

            this.OrderGarmentActionGroupItemCollection.DeleteMultiManyToOne(null, this, null);

            base.OnValidateEntityBeforeDelete();
        }

        protected override void OnDelete()
        {
            if (this.OrderItemClothingCollection.Count > 0)
            {
                throw new Exception("Entity can not be deleted because of it having childeren.");
            }

            this.OrderGarmentActionGroupItemCollection.DeleteMultiManyToOne(null, this, null);

            base.OnDelete();
        }

I've also after my post upgraded to version 2.5 but the problem persists.

Thanks for any additional pointers and suggestions,

Gab

gabrielk avatar
gabrielk
User
Posts: 231
Joined: 01-Feb-2005
# Posted on: 09-Nov-2007 15:29:30   

Additional Info:

My structure is like:

Order - OrderGarmentActionGroup - OrderGarmentActionGroupItem - OrderGarmentActionGroupItemColor

If I do a direct delete call on Order only the OnDelete code of Order is executed which deletes all OrderGarmentActionGroups

If I do a direct delete on OrderGarmentActionGroup only the OnDelete code of OrderGarmentActionGroup is executed which deletes all OrderGarmentActionGroupItems

etc..

So if I delete an Order the OrderGarmentActionGroupItems and OrderGarmentActionGroupItemColors are not being removed. So I guess there's something different in how the .Delete is called from the DeleteMulti and with a Delete on the Entity.

.. Still puzzled

Cheers, Gab

gabrielk avatar
gabrielk
User
Posts: 231
Joined: 01-Feb-2005
# Posted on: 09-Nov-2007 16:36:03   

I've now implemented the following old code:


        protected override void OnDelete()
        {
            this.OrderGarmentActionGroupCollection.DeleteMultiManyToOne(this);
            base.OnDelete();        
        }

with this code:


            for (int i = 0; i < this.OrderGarmentActionGroupCollection.Count; i++)
            {
                this.OrderGarmentActionGroupCollection[i].Delete();
            }

And it works like a charm simple_smile The OnDeletes all get invoked now...

I can't get the ORMSupportClasses debugged, so for the time being this has to be my solution...

On the ORMClass debug issue:

We referenced to the DebugBuild version of the RuntimeFolder of LLBL 2.5, we got the PDB file in the build folder, but when we step into (Funtion key: F11) DeleteMulti() it just won't get in.. What did we do wrong?

Thanks, Gab

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39908
Joined: 17-Aug-2003
# Posted on: 09-Nov-2007 20:43:16   

We referenced to the DebugBuild version of the RuntimeFolder of LLBL 2.5, we got the PDB file in the build folder, but when we step into (Funtion key: F11) DeleteMulti() it just won't get in.. What did we do wrong?

In the first post you state you're using v2.0, not v2.5 wink

Do you use v2.5? Because this behavior sounds familiar to something which was fixed during v2.5 development

Frans Bouma | Lead developer LLBLGen Pro
gabrielk avatar
gabrielk
User
Posts: 231
Joined: 01-Feb-2005
# Posted on: 11-Nov-2007 22:14:38   

Hi,

I've also after my post upgraded to version 2.5 but the problem persists.

Indeed as I posted in my 2nd message, I upgraded in the mean time just with the problem would simply disappear simple_smile

The problem is still the same.

Can I give any more help or details?

Thanks, Gab

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39908
Joined: 17-Aug-2003
# Posted on: 12-Nov-2007 11:41:11   

The reason OnDelete isn't called is because DeleteMultiManyToOne performs a delete directly onto the db. So it doesn't delete entities one by one which are in memory. This means that OnDelete can't be called, as there's no entity in memory to delete, it's a delete directly on the db.

So look into AuditDirectDeleteOfEntities instead simple_smile

Frans Bouma | Lead developer LLBLGen Pro
gabrielk avatar
gabrielk
User
Posts: 231
Joined: 01-Feb-2005
# Posted on: 12-Nov-2007 13:19:48   

Hi,

I can't find AuditDirectDeleteOfEntities in the help file. Where or what is it?

Isn't it strange that an entity can get deleted without the Delete events being executed? I would say this should be mentioned somewhere in the manual. And if it is already it is not obvious yet.

Is this done together with the Auditing in 2.5, or can it be done with 2.0 also?

Is this direct to db behavior the same for SaveMulti()? If it's not it's inconsistent, if it is i have problem simple_smile

Btw, what I find strange is this code in the ORM Supportclasses:


private int PerformDeleteMulti()
{
(...)
                bool wasSuccesful = entityToDelete.Delete();
(...)
}

Thanks, Gab

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39908
Joined: 17-Aug-2003
# Posted on: 12-Nov-2007 14:29:27   

gabrielk wrote:

Hi, I can't find AuditDirectDeleteOfEntities in the help file. Where or what is it?

bug in the docs, I'll fix that a.s.a.p. Please check: Using the generated code -> Setting up and using Auditing -> Location of your auditing logic: OnAuditDirectDeleteOfEntities.

Isn't it strange that an entity can get deleted without the Delete events being executed? I would say this should be mentioned somewhere in the manual. And if it is already it is not obvious yet.

It's obvious IMHO that these events aren't raised. You seem to confuse two things: a) DeleteMulti() and b) DeleteMulti(filter [, relations])

The first deletes all entities in the collection it's called on. The second deletes all entities from the DB of the type the collection belongs to with the filter specified.

In the case of a) it calls the OnDelete method every time an entity is about to be deleted, namely for every entity in the collection. In the case of b) it can't do that, because the filter might match 1 million rows. Do you want to fetch them first into memory, then call the OnDelete on every row and then delete them? wink That's pretty slow I think, so it won't do that. So because of the uncertainty which rows match with the filter, the OnDelete method can't be called.

Is this done together with the Auditing in 2.5, or can it be done with 2.0 also?

In v2.5, you can audit a call to DeleteMulti(filter), however it's not possible to prevent the deletion there, auditing is always 'mosterd na de maaltijd' so to say wink

An authorizer can prevent deletion, but it works on types. So you can't prevent 'certain' entities to be deleted, as you then first have to check if the entities not to be deleted match the filter.

Is this direct to db behavior the same for SaveMulti()? If it's not it's inconsistent, if it is i have problem simple_smile

SaveMulti always works on entities in memory, similar to DeleteMulti(), so that's consistent. SaveMulti doesn't work on the DB directly.

Btw, what I find strange is this code in the ORM Supportclasses:


private int PerformDeleteMulti()
{
(...)
                bool wasSuccesful = entityToDelete.Delete();
(...)
}

Thanks, Gab

That's the call for DeleteMulti() (no filter). Not the one which deletes entities directly.

If you want to prevent the deletion of a certain entity in certain cases, it's perhaps better to override DeleteMulti(filter) and DeleteMulti(filter, relations) in the collection of the entity and simply prevent one calls these methods (so entities always have to be fetched first), i.e. by throwing an exception.

That won't affect DeleteMulti() (no filter!), as that's a different routine.

Are these overloads stupid, or not chosen correctly? Of course. But as they're part of the oldest core of LLBLGen Pro, there's no ability to change them.

Frans Bouma | Lead developer LLBLGen Pro
gabrielk avatar
gabrielk
User
Posts: 231
Joined: 01-Feb-2005
# Posted on: 12-Nov-2007 14:47:04   

Thanks for the complete info on this. We will use it with the overloads or auditing then.

Cheers, Gab