Blood concurrency - my head hurts

Posts   
 
    
BOb
User
Posts: 12
Joined: 29-Jun-2005
# Posted on: 27-Oct-2005 16:56:49   

I am having all sorts of problems to get any sort of concurrency testing to work

I know that I should be setting the ConcurrencyProdicateFactoryToUse but I cannot get it to work

I can get something to compile but when it runs I get a casting error (using 1.0.2005) :-

System.Web.Services.Protocols.SoapException was unhandled Message=System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.InvalidCastException: Unable to cast object of type 'SD.LLBLGen.Pro.ORMSupportClasses.PredicateExpression' to type 'SD.LLBLGen.Pro.ORMSupportClasses.IConcurrencyPredicateFactory'.

I have ripped a piece of code from the forum to create my factory :-

public IPredicateExpression CreatePredicate (ConcurrencyPredicateType typeToCreate, object containingEntity) { IPredicateExpression concurrencyPredicate = new PredicateExpression(); IEntity2 entity = (IEntity2)containingEntity; if (entity.Fields["RowVersion"] != null && typeToCreate == ConcurrencyPredicateType.Save) { concurrencyPredicate.Add( new FieldCompareValuePredicate(entity.Fields["RowVersion"], null, ComparisonOperator.Equal)); } return concurrencyPredicate; }

I am in danger of dissapearing up my own backside at this rate ...

All I want to do is use a field by the name of ADD_Concurrency (in my Address class and also in an AddressEntity as generated by LLB) to be compared to the one currently in the database at the time I am doing an update

All of this is being performed statelessly, so the ADD_Concurrency field is being passed to the client at the time of the read and then passed back to the server at the time of the update. When I perform the update, I need to compare the current value with the one that was read earlier.

Any help gratefully received

Thanks

BOb

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39749
Joined: 17-Aug-2003
# Posted on: 27-Oct-2005 17:09:22   

How and where do you set the ConcurrencyPredicateFactoryToUse to an instance of that factory? The error seems strange. I'll look into the code for serialization as well to see if I made a mistake somewhere...

(edit) I add the proper objects to the right names, so I don't see a reason it should be deserialized as a predicate expression...

Frans Bouma | Lead developer LLBLGen Pro
BOb
User
Posts: 12
Joined: 29-Jun-2005
# Posted on: 27-Oct-2005 17:21:53   

I did not understand your [edit] comment

To answer your other question here is the code I use :-

addressEntity.ConcurrencyPredicateFactoryToUse = (IConcurrencyPredicateFactory) toSave.CreatePredicate(ConcurrencyPredicateType.Save, addressEntity);

where toSave is an Address object and addressEntity is a local variable of type AddressesEntity (auto generated by LBL)

Is this what you wanted to see ?

BOb

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39749
Joined: 17-Aug-2003
# Posted on: 27-Oct-2005 18:22:26   

BOb wrote:

I did not understand your [edit] comment

I checked if I messed up somewhere in the deserialization code (which would be weird as the unittests succeeded), but I didn't.

To answer your other question here is the code I use :-

addressEntity.ConcurrencyPredicateFactoryToUse = (IConcurrencyPredicateFactory) toSave.CreatePredicate(ConcurrencyPredicateType.Save, addressEntity);

where toSave is an Address object and addressEntity is a local variable of type AddressesEntity (auto generated by LBL)

Is this what you wanted to see ?

Yes, and the code isn't ok.

ConcurrencyPredicateFactoryToUse should be an implementation of IConcurrencyPredicateFactory. CreatePredicate() creates a PredicateExpression, which is a totally different object.

So what you should do is set the property ConcurrencyPredicateFactoryToUse of the entity object you want to save to an instance of the IConcurrencyPredicateFactory implementation, and simply save the entity object. The save logic will check if a ConcurrencyPredicateFactoryToUse is set, and if so, will request a predicate from it to use for the update (inserts are ignoring ConcurrencyPredicateFactoryToUse ). So the predicateexpression you should return in the CreatePredicate method of your IConcurrencyPredicateFactory implementing class is a predicateexpression which compares a field with a value, exactly like you're doing.

You can set the ConcurrencyPredicateFactoryToUse property on the client and send the entity to the server via remoting. It will be serialized into the entity automatically and deserialized at the server automatically.

Frans Bouma | Lead developer LLBLGen Pro