UnitOfWork2.AddForDelete

Posts   
 
    
saggett
User
Posts: 50
Joined: 12-Nov-2007
# Posted on: 26-Feb-2009 14:51:45   

Using latest version (February 6th) of LLBLGen 2.6, using Adapter.

I have a question about the following code, taken from the UnitOfWork2 class.


/// <summary>
/// Adds the passed in object for delete. This is the actual routine performing the work.
/// </summary>
/// <param name="entityToDelete">Entity to delete.</param>
/// <param name="restriction">Restriction.</param>
/// <param name="append">If true (default), append the entity at the end of the list, otherwise insert it at the front. False in the case
/// of inserting objects from collections marked for deletion.</param>
internal bool AddForDelete(IEntity2 entityToDelete, IPredicateExpression restriction, bool append)
{
    bool accept = false;
    UnitOfWorkElement2 newElement = null;
    if(!entityToDelete.IsNew)
    {
        if(!_objectIDsToDelete.ContainsKey(entityToDelete.ObjectID))
        {
            // accept
            accept = true;
            newElement = new UnitOfWorkElement2(entityToDelete, restriction);
            _objectIDsToDelete.Add(entityToDelete.ObjectID, newElement);
            if(append)
            {
                _entitiesToDelete.Add(newElement);
            }
            else
            {
                _entitiesToDelete.Insert(0, newElement);
            }
        }
    }
    else
    {
        // check if this entity is added for save as well. if so, remove it from the save queue.
        if(_objectIDsToSave.ContainsKey(entityToDelete.ObjectID))
        {
            UnitOfWorkElement2 element = _objectIDsToSave[entityToDelete.ObjectID];
            _objectIDsToSave.Remove(entityToDelete.ObjectID);
            _entitiesToSave.Remove(element);
        }
    }

    return accept;
}

I'm passing in a new entity with the primary key set, like so:


unitOfWork.AddForDelete(new SensitivityPriceGroupEntity() { Id = sensPriceGroupId });

But given that the entity is new, the method returns without having added the entity to the delete queue. Hence nothing gets deleted. I was expecting this to be added to the Unit of Work, and on commit result in the deletion of the SensitivityPriceGroup row with primary key equal to sensPriceGroupId. What's going on?

Incidentally, SensitivityPriceGroupEntity is in a target-per-entity hierarchy and inherits from SensitivityEntity, which is why I'm not deleting it by calling DeleteEntitiesDirectly (I was, until I discovered that the Sensitivity rows weren't getting deleted).

saggett
User
Posts: 50
Joined: 12-Nov-2007
# Posted on: 26-Feb-2009 17:20:08   

I've just noticed this thread, seems to relate to the same issue.

http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=2241

MTrinder
User
Posts: 1461
Joined: 08-Oct-2008
# Posted on: 26-Feb-2009 21:09:09   

As it says in that thread AddForDelete only works on non-new entities. To delete entities directly in a UnitOfWork (ie without having to load them first), use .AddDeleteEntitiesDirectlyCall( )

Matt

saggett
User
Posts: 50
Joined: 12-Nov-2007
# Posted on: 02-Mar-2009 18:06:19   

This is what I've come up with for the .AddDeleteEntitiesDirectlyCall():


var sensPfFilter = new RelationPredicateBucket(SensitivityProductFamilyFields.Id == sensProdFamId);
unitOfWork.AddDeleteEntitiesDirectlyCall(typeof(SensitivityProductFamilyEntity), sensPfFilter);
var sensFilter = new RelationPredicateBucket(SensitivityFields.Id == sensProdFamId);
unitOfWork.AddDeleteEntitiesDirectlyCall(typeof (SensitivityEntity).Name, sensFilter);

It works but it's not ideal or obvious. Could I request that the AddForDelete() method be improved to support deletion of new entities, or at least it be made more obvious in the documentation that passing in a new entity with primary key set will not result in that entity being deleted? The vast majority of LLBLGen methods work as one would expect but this would seem to be an exception to that rule.

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 03-Mar-2009 10:44:07   

Please try the following code:

SensitivityPriceGroupEntity entity = new SensitivityPriceGroupEntity(sensPriceGroupId);
entity.IsNew = false;
unitOfWork.AddForDelete(entity);
saggett
User
Posts: 50
Joined: 12-Nov-2007
# Posted on: 03-Mar-2009 15:19:08   

I've now tried that, and I suspect it would have worked if I didn't have a timestamp column on the Sensitivity table. The delete statement is generated as follows:


DELETE FROM [UnivarQ].[dbo].[SensitivityPriceGroup] FROM ( [UnivarQ].[dbo].[Sensitivity]  INNER JOIN [UnivarQ].[dbo].[SensitivityPriceGroup]  ON  [UnivarQ].[dbo].[Sensitivity].[Id]=[UnivarQ].[dbo].[SensitivityPriceGroup].[Id]) WHERE ( ( [UnivarQ].[dbo].[SensitivityPriceGroup].[Id] = @Id1) AND ( ( [UnivarQ].[dbo].[Sensitivity].[Timestamp] IS NULL)))

This query would be entirely suitable if the entity had just been fetched from the database - in that case the Timestamp would have a value, and the WHERE condition would make more sense.

Which results in a ORMConcurrencyException with the message "The delete action of an entity failed, probably due to the set delete restriction. The entity which failed is enclosed." when the UnitOfWork2 is committed.

I think I'll have to go with my workaround - unless there's anything else I should try?

MTrinder
User
Posts: 1461
Joined: 08-Oct-2008
# Posted on: 03-Mar-2009 21:17:33   

I think your work around is the way to go simple_smile

Matt