IConcurrencyPredicateFactory

Posts   
 
    
Posts: 19
Joined: 08-Jan-2007
# Posted on: 13-Feb-2007 16:50:55   

Hi

I'm not sure if I'm missing something here. I have created a partial class for my entity, added the IConcurrencyPredicateFactory interface to the class declaration, and implemented the CreatePredicate() method.

The documentation seems to indicate that the LLBL framework will detect that the interface has been implemented and call the method. However it doesn't seem to be getting called when I save (update) the entity. Am I missing something - should I be implementing or overriding something else? This is my partial class:


    public partial class DocumentEntity : IConcurrencyPredicateFactory
    {
        public IPredicateExpression CreatePredicate(
            ConcurrencyPredicateType predicateTypeToCreate,
            object containingEntity)
        {
            IPredicateExpression expression = new PredicateExpression();

            DocumentEntity document = (DocumentEntity)containingEntity;

            switch (predicateTypeToCreate)
            {
                case ConcurrencyPredicateType.Save:
                    expression.Add(DocumentFields.Timestamp == document.Fields[(int)DocumentFieldIndex.Timestamp].DbValue);
                    break;
            }

            return expression;
        }
    }

It seems to work if I add this to my partial class, but it seems a bit unnecessary:


        public override IPredicateExpression GetConcurrencyPredicate(ConcurrencyPredicateType predicateTypeToCreate)
        {
            return CreatePredicate(predicateTypeToCreate, this);
        }

Thanks in advance

Andy

jbb avatar
jbb
User
Posts: 267
Joined: 29-Nov-2005
# Posted on: 13-Feb-2007 17:19:54   

Hello,

If you don't overides the GetConcurrencyPredicate function, what happend? Did it throw an exception or never go to your CreatePredicate function?

Posts: 19
Joined: 08-Jan-2007
# Posted on: 13-Feb-2007 17:25:07   

Hi,

If I don't override GetConcurrencyPredicate() as above, it never goes into the CreatePredicate() method.

Regards Andy

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 14-Feb-2007 08:19:36   

Nothing is wrong in the above posted scenario.

The documentation says, you should implement the IConcurrencyPredicateFactory in a class (other than the entity), then you should set the entity's ConcurrencyPredicateFactoryToUse to an istance of this class.

That's how an entity detects the concurrency predicate itself.

But you implemented the CreatePredicate method inside the entity, then you should call it from the GetConcurrencyPredicate method.

Posts: 19
Joined: 08-Jan-2007
# Posted on: 14-Feb-2007 09:55:44   

Hi

Thanks for the reply.

If I create the IConcurrencyPredicateFactory as a separate class, where would be the best place to set ConcurrencyPredicateFactoryToUse in an entity partial class? Should I override the OnInitializing() method and put it in there?

And one last question - we use the same concurrency technique for each database table (a timestamp column). How can I convert my earlier example code to be generic, so it can be used with any entity, not just the "DocumentEntity" fields?

Thanks again

Andy

Posts: 19
Joined: 08-Jan-2007
# Posted on: 14-Feb-2007 13:06:24   

Doh, not enough coffee this morning.

I realised I can just override the GetConcurrencyPredicate method in my entity partial class.

Regards creating a generic concurrency predicate factory that I can use with any entity (that has a Timestamp field), I have come up with this solution. It seems to work but just wanted to run it by you to make sure it looks okay:


        public IPredicateExpression CreatePredicate(
            ConcurrencyPredicateType predicateTypeToCreate,
            object containingEntity)
        {
            EntityBase2 entity = (EntityBase2)containingEntity;

            EntityField2 timestampField = 
                (EntityField2)EntityFieldFactory.Create(entity.GetType().Name, "Timestamp");

            IPredicateExpression expression = new PredicateExpression();

            switch (predicateTypeToCreate)
            {
                case ConcurrencyPredicateType.Save:
                    expression.Add(timestampField == entity.Fields["Timestamp"].DbValue);
                    break;
            }

            return expression;
        }

Thanks again

Andy

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 14-Feb-2007 16:45:22   

If I create the IConcurrencyPredicateFactory as a separate class, where would be the best place to set ConcurrencyPredicateFactoryToUse in an entity partial class? Should I override the OnInitializing() method and put it in there?

The following is copied from the manual:

To set an IConcurrencyPredicateFactory object when an entity is created or initialized, please see the section Adding your own code to the generated classes which discusses various ways to modify the generated code to add your own initialization code which for example sets the IConcurrencyPredicateFactory instance for a particular object. You can also set an IConcurrencyPredicateFactory instance of an entity using the ConcurrencyPredicateFactoryToUse property of an entity collection to automatically set the ConcurrencyPredicateFactoryToUse property of an entity when it's added to the particular entity collection.

I think you've got that generic predicate correct.