ConcurrencyPredicateFactoryToUse on Collections

Posts   
 
    
ianvink
User
Posts: 394
Joined: 15-Dec-2006
# Posted on: 02-Jan-2007 03:13:18   

I have a collection of customers "_cc" and each customer has a collection of orders.

I created a concurrency class:

public class **CustomerConcurrencyFilterFactory **: IConcurrencyPredicateFactory { ... }

and set this class to the collection's **ConcurrencyPredicateFactoryToUse **

     _cc.ConcurrencyPredicateFactoryToUse = new CustomerConcurrencyFilterFactory();
     _cc.SaveMulti();

The **CustomerConcurrencyFilterFactory **never is called though. I do ensure that there are customers with dirty data. In fact the customer's changed data does save.

Any idea why the **CustomerConcurrencyFilterFactory **is not called?

Here is the full class:


public class CustomerConcurrencyFilterFactory : IConcurrencyPredicateFactory
    {
        public IPredicateExpression CreatePredicate(
            ConcurrencyPredicateType predicateTypeToCreate, object containingEntity)
        {
            IPredicateExpression toReturn = new PredicateExpression();
            CustomersEntity customer = (CustomersEntity)containingEntity;

            switch (predicateTypeToCreate)
            {
                case ConcurrencyPredicateType.Delete:
                    toReturn.Add(CustomersFields.Country == customer.Fields[(int)CustomersFieldIndex.Country].DbValue);
                    break;
                case ConcurrencyPredicateType.Save:
                    // only for updates
                    toReturn.Add(CustomersFields.Country == customer.Fields[(int)CustomersFieldIndex.Country].DbValue);
                    break;
            }
            return toReturn;
        }
    }
ianvink
User
Posts: 394
Joined: 15-Dec-2006
# Posted on: 02-Jan-2007 03:16:03   

Forgot to mention:

Newest V2 build as of Dec 20 on VS.NET 2005 in C#

ianvink
User
Posts: 394
Joined: 15-Dec-2006
# Posted on: 02-Jan-2007 03:40:27   

As a test I added this line:


IConcurrencyPredicateFactory concur = new CustomerConcurrencyFilterFactory();
_cc.DirtyEntities[0].ConcurrencyPredicateFactoryToUse = concur;

before the save to test it. Now the concurrency class does get hit and it adds the correct predicate. But the save doesn't throw an error when I on purpose change what I should not.

Is there something I am missing to get the concurrency to check values and to work when I only set the Collection.ConcurrencyPredicateFactoryToUse value?

Ian

ianvink
User
Posts: 394
Joined: 15-Dec-2006
# Posted on: 02-Jan-2007 04:40:40   

I have it now throwing concurrency errors correctly.

Now I only need to understand why setting ConcurrencyPredicateFactoryToUse on the collection doesn't seem to do anything.

Here's the SQL it makes when ConcurrencyPredicateFactoryToUse is set on the collection level only:


    Query: UPDATE [Northwind].[dbo].[Customers] SET [Region]=@Region,[Country]=@Country WHERE ( [Northwind].[dbo].[Customers].[CustomerID] = @CustomerId1)
    Parameter: @Region : String. Length: 15. Precision: 0. Scale: 0. Direction: Input. Value: "Australiaff".
    Parameter: @Country : String. Length: 15. Precision: 0. Scale: 0. Direction: Input. Value: "Germanyfff".
    Parameter: @CustomerId1 : StringFixedLength. Length: 5. Precision: 0. Scale: 0. Direction: Input. Value: "ALFKI".
Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 02-Jan-2007 06:03:46   

When you set the ConcurrencyPredicateFactoryToUse of an EntityCollection, only those entities added to the collection afterwards get their ConcurrencyPredicateFactoryToUse set by the same value.

Copied from the docs (Concurrency control):

You can also set an IConcurrencyPredicateFactory instance of an entity using the ConcurrencyPredicateFactoryToUse property of an EntityCollection to automatically set the ConcurrencyPredicateFactoryToUse property of an entity when it's added to the particular entity collection.

Copied from the reference manual (ConcurrencyPredicateFactoryToUse Property of the EntityCollectionBase class):

Gets / sets the IConcurrencyPredicateFactory instance to use when creating entity objects during a GetMulti() call or when AddNew is called.

ianvink
User
Posts: 394
Joined: 15-Dec-2006
# Posted on: 11-Jan-2007 06:51:56   

Hi,

I tried this:

TaskCollection taskCollection = new TaskCollection();
TaskConcurrencyFilterFactory con = new TaskConcurrencyFilterFactory();

taskCollection.ConcurrencyPredicateFactoryToUse =  con;
taskCollection.GetMulti(null);

but taskCollection[0].ConcurrencyPredicateFactoryToUse is null after the GetMulti()

Any ideas what I am doing wrong? Ian

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39918
Joined: 17-Aug-2003
# Posted on: 11-Jan-2007 12:06:33   

I can reproduce it, but I have no idea why it happens, as in the fetch logic it does set the factory. Looking into it.

(edit) found it. Silly bug. Fixed in next build (2.0.07.0111)

Frans Bouma | Lead developer LLBLGen Pro
ianvink
User
Posts: 394
Joined: 15-Dec-2006
# Posted on: 15-Jan-2007 02:19:43   

Otis wrote:

I can reproduce it, but I have no idea why it happens, as in the fetch logic it does set the factory. Looking into it.

(edit) found it. Silly bug. Fixed in next build (2.0.07.0111)

Confirmed new version fixed issue.

Ian

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 15-Jan-2007 08:16:55   

Thanks for the feedback