IConcurrencyPredicateFactory question

Posts   
 
    
carlor
User
Posts: 34
Joined: 12-Jan-2005
# Posted on: 11-Feb-2005 17:09:41   

Hi there,

I'm doing some work trying to figure out a good concurrency model for our web application. I have added the code outlined in the help file under SelfServicing - Using the entity classes - Concurrency Control. This works for a simple entity.

Now, I want to be able to handle concurrency for an entity that contains collections of other entities... and those "other entities" may have collections of other entities, and so on.

In the documentation it mentions:

If you want concurrency control deep down a recursive save, it's key that you set those object's ConcurrencyPredicateFactoryToUse property to an instance of IConcurrencyPredicateFactory

Does this mean that I must manually set the ConcurrencyPredicateFactoryToUse for each object in the above mentioned hierarchy? If this is the case, would it be better to create "intermediate" classes derived from the entities in which the constructors would set the ConcurrencyPredicateFactoryToUse?

Thanks,

Carlo.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39835
Joined: 17-Aug-2003
# Posted on: 12-Feb-2005 21:00:48   

Please see this thread: http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=992&StartAtMessage=25#5838

The init method of the class doesn't yet include an include template, which should be the case. This is added soon. For the time being you can either use the solution in that thread (it's a long thread with various options which didn't work, but at least one which did simple_smile ) or you can write a factory for entities (or extend the default factory) which insert teh concurrencypredicatefactory instance of your liking..

Frans Bouma | Lead developer LLBLGen Pro
carlor
User
Posts: 34
Joined: 12-Jan-2005
# Posted on: 15-Feb-2005 15:44:28   

Thank you for your reply. Could you briefly describe what you mean by:

write a factory for entities (or extend the default factory) which insert teh concurrencypredicatefactory instance

Thank you,

Carlo.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39835
Joined: 17-Aug-2003
# Posted on: 15-Feb-2005 16:26:32   

There is a default factory generated, called GeneralEntityFactory. This class contains a Create method to which you can pass the EntityType of the entity you want and it creates that entity for you.

See EntityFactories.cs in FactoryClasses for details.

You can easily generate such a class yourself or adjust the template used for that class. You can then add your concurrencypredicatefactory instance there and always do: CustomerEntity c = GeneralEntityFactory.Create(EntityType.CustomerEntity);

The downside of that last trick is that with entity collection fetches you need the entity factories to be adjusted as well, as these are used when fetching an entity collection.

Adapter makes this a lot easier, as you can simply create extended factories as you always specify the factory anyway with adapter.

Frans Bouma | Lead developer LLBLGen Pro
carlor
User
Posts: 34
Joined: 12-Jan-2005
# Posted on: 16-Feb-2005 17:09:23   

So, are you saying then, that if I modify an entity in a collection in an entity, I have to set the lower level's entity's ConcurrencyPredicateFactoryToUse property for each entity that I modify?

i.e.


anEntity.anEntityCollection(0).field1 = "New Value"
anEntity.anEntityCollection(0).ConcurrencyPredicateFactoryToUse = new MyConcurrencyFactory

anEntity.anEntityCollection(3).field2 = "this field changed"
anEntity.anEntityCollection(3).ConcurrencyPredicateFactoryToUse = new MyConcurrencyFactory

anEntity.field3 = "another different value"
anEntity.ConcurrencyPredicateFactoryToUse = new MyOtherConcurrencyFactory

anEntity.save()


Thanks,

Carlo.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39835
Joined: 17-Aug-2003
# Posted on: 16-Feb-2005 19:19:19   

Yes, and if you modify the factory, you don't have this problem as all entities in that collection are created using the entity factory.

The template set CSharpTemplateSet.config binds entityFactoryInclude.template to SD_EntityFactoryIncludeTemplate.

if you create a copy of the CSharpTemplateSet.config, and alter that binding to another file and copy teh entityFactoryInclude.template file's contents into that file + your own code, you'll get your own custom factories simple_smile If you need an example for this, please let me know.

This is a bit if a burden for potential customers, so we will offer a generator which preserves user code in the generator code in March

Frans Bouma | Lead developer LLBLGen Pro
carlor
User
Posts: 34
Joined: 12-Jan-2005
# Posted on: 17-Feb-2005 21:25:48   

Hello again,

Thank you for all your help. Yes, a sample would be very much appreciated simple_smile

Thank you,

Carlo.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39835
Joined: 17-Aug-2003
# Posted on: 18-Feb-2005 09:46:42   

carlor wrote:

Hello again,

Thank you for all your help. Yes, a sample would be very much appreciated simple_smile Thank you, Carlo.

if you create a copy of the CSharpTemplateSet.config, and alter that binding to another file and copy teh entityFactoryInclude.template file's contents into that file + your own code, you'll get your own custom factories

Ok here we go: 1) copy CSharpTemplateset.config in <llblgenpro folder>\Drivers\SqlServer\Templates to CustomCSharpTemplateset.config in the same folder 2) open CustomCSharpTemplateset.config in an editor (it's xml) 3) change the <name> contents so you'll recognize it in the dropdown in the generator config form in LLBLGen Pro 4) scroll down to this tag:


<templateBinding templateID="SD_EntityFactoryIncludeTemplate" templateFilename="..\..\..\SharedTemplates\C#\entityFactoryInclude.template" />

and alter it into:


<templateBinding templateID="SD_EntityFactoryIncludeTemplate" templateFilename="..\..\..\SharedTemplates\C#\myEntityFactoryInclude.template" />

and save the file. 5) copy <llblgen pro folder>\SharedTemplates\C#\entityFactoryInclude.template to myEntityFactoryInclude.template in the same folder and open it in a texteditor 6) you'll see one line:


            return new <[CurrentEntityName]>Entity(new PropertyDescriptorFactory(), this);

change this into:


IEntity toReturn = <[CurrentEntityName]>Entity(new PropertyDescriptorFactory(), this);
toReturn.ConcurrencyPredicateFactoryToUse = new MyConcurrencyPredicateFactory();
return toReturn;

If you have a ConcurrencyPredicateFactory per entity, you can change ' new MyConcurrencyPredicateFactory' into 'new <[CurrentEntityName]>ConcurrencyPredicateFactory' to get the entity name generated into the call. Save the file.

Now, when you generate code, select your custom csharp template set and generate code. Your selfservicing entity factories now will create the concurrency predicate factory classes as well. Place your concurrency predicate classes in the same namespace: <rootnamespace>.FactoryClasses, so your code will be compilable.

Frans Bouma | Lead developer LLBLGen Pro