Recursive Save results in ORMConcurrencyException

Posts   
 
    
saggett
User
Posts: 50
Joined: 12-Nov-2007
# Posted on: 01-May-2008 16:34:58   

Using LLBLGen v2.5 March 28th 2008 Final, targeting .NET 3.0, Adapter, C#.

When debugging I'm getting a ORMConcurrencyException when recursively saving a hierarchy. Each of the entities in the hierarchy inherit from the same base class, SensitivityEntity.

Here's the code I'm running. A just fetched, clean, SensitivityCustomerEntity is being passed to CreateCustomerSensitivities. When building up the hierarchy within CreateCustomerSensitivities I'm setting the root entity to dirty so that the save will go ahead. Everything's happening serverside so no serialization complications.

Building up the hierarchy:

        public void CreateCustomerSensitivities(SensitivityCustomerEntity sensCust, QuoteEntity quote)
        {

            foreach (QuoteProductEntity quoteProduct in quote.QuoteProducts)
            {
                ProductEntity product = quoteProduct.Product;
                SensitivityProductFamilyEntity sensProdFam = FindSensitivityProductFamily(sensCust, product.PriceGroup.ProductFamilyId);
                if (sensProdFam == null)
                    sensProdFam = AddProductFamilySensitivity(sensCust, quote.EmailAddress, product.PriceGroup.ProductFamilyId);
                SensitivityItemGroupEntity sensItemGroup = FindSensitivityItemGroup(sensProdFam, product.PriceGroup.ItemGroupId);
                if (sensItemGroup == null)
                    sensItemGroup = AddItemGroupSensitivity(sensCust, sensProdFam, quote.EmailAddress, product.PriceGroup.ItemGroupId);
                SensitivityPriceGroupEntity sensPg = FindSensitivityPriceGroup(sensItemGroup, product.PriceGroupId);
                if (sensPg == null)
                    sensPg = AddPriceGroupSensitivity(sensCust, sensItemGroup, quote.EmailAddress, product.PriceGroupId);
            }

            var sensCustWorker = new UnivarQ.DataGateway.SensitivityCustomerWorker();
            sensCustWorker.SaveSensitivityCustomer(sensCust, null, null, null, false);
        }

        private SensitivityPriceGroupEntity AddPriceGroupSensitivity(SensitivityCustomerEntity sensCust, SensitivityItemGroupEntity sensItemGroup,
                                                 string quoteEmailAddress, int priceGroupId)
        {
            var sensPg = new SensitivityPriceGroupEntity();
            InitializeSensitivityEntity(sensCust, quoteEmailAddress, sensPg);
            sensPg.PriceGroupId = priceGroupId;
            sensItemGroup.SensitivityPriceGroups.Add(sensPg);
            sensCust.IsDirty = true;
            return sensPg;
        }

        private SensitivityItemGroupEntity AddItemGroupSensitivity(SensitivityCustomerEntity sensCust, SensitivityProductFamilyEntity sensProdFam, string quoteEmailAddress, int itemGroupId)
        {
            var csItemGroup = new SensitivityItemGroupEntity();
            InitializeSensitivityEntity(sensCust, quoteEmailAddress, csItemGroup);
            csItemGroup.ItemGroupId = itemGroupId;
            sensProdFam.SensitivityItemGroups.Add(csItemGroup);
            sensCust.IsDirty = true;
            return csItemGroup;
        }

        private SensitivityProductFamilyEntity AddProductFamilySensitivity(SensitivityCustomerEntity sensCust,
                                                 string quoteEmailAddress, int productFamilyId)
        {
            var sensProdFam = new SensitivityProductFamilyEntity();
            InitializeSensitivityEntity(sensCust, quoteEmailAddress, sensProdFam);
            sensProdFam.ProductFamilyId = productFamilyId;
            sensCust.SensitivityProductFamilies.Add(sensProdFam);
            sensCust.IsDirty = true;
            return sensProdFam;
        }

Persisting to DB:

        public SensitivityCustomerEntity SaveSensitivityCustomer(SensitivityCustomerEntity sensCust,
                                    List<int> csPriceGroupIdsToDelete,
                                    List<int> csItemGroupIdsToDelete,
                                    List<int> csProductFamilyIdsToDelete, 
                                    bool refetch)
        {

            if ((csPriceGroupIdsToDelete == null || csPriceGroupIdsToDelete.Count == 0) &&
                (csItemGroupIdsToDelete == null || csItemGroupIdsToDelete.Count == 0) &&
                (csProductFamilyIdsToDelete == null || csProductFamilyIdsToDelete.Count == 0) &&
                (sensCust != null && sensCust.IsDirty))
            {
                //if we have nothing to delete, do a normal recursive save
                SaveEntity(sensCust, true, true);
                return sensCust;
            }

This is the exception I get:

Type : SD.LLBLGen.Pro.ORMSupportClasses.ORMConcurrencyException, SD.LLBLGen.Pro.ORMSupportClasses.NET20, Version=2.5.0.0, Culture=neutral, PublicKeyToken=ca73b74ba4e3ff27 Message : During a save action an entity's update action failed. The entity which failed is enclosed. Source : SD.LLBLGen.Pro.ORMSupportClasses.NET20 Help link : EntityWhichFailed : UnivarQ.DAL.EntityClasses.SensitivityCustomerEntity RuntimeVersion : 2.5.0.0 RuntimeBuild : 03282008 Data : System.Collections.ListDictionaryInternal TargetSite : Boolean PersistQueue(System.Collections.Generic.List1[SD.LLBLGen.Pro.ORMSupportClasses.ActionQueueElement1[SD.LLBLGen.Pro.ORMSupportClasses.IEntity2]], Boolean, Int32 ByRef) Stack Trace : at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.PersistQueue(List1 queueToPersist, Boolean insertActions, Int32& totalAmountSaved) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v2.0\RuntimeLibraries 2.5 .NET 2.x\ORMSupportClasses\DataAccessAdapterBase.cs:line 1712 at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.SaveEntity(IEntity2 entityToSave, Boolean refetchAfterSave, IPredicateExpression updateRestriction, Boolean recurse) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v2.0\RuntimeLibraries 2.5 .NET 2.x\ORMSupportClasses\DataAccessAdapterBase.cs:line 1491 at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.SaveEntity(IEntity2 entityToSave, Boolean refetchAfterSave, Boolean recurse) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v2.0\RuntimeLibraries 2.5 .NET 2.x\ORMSupportClasses\DataAccessAdapterBase.cs:line 1350 at UnivarQ.DataGateway.Worker.SaveEntity(IEntity2 entity, Boolean recurse, Boolean refetchAfterSave) in C:\Projects\UnivarQ\Current\Product\Production\Facade\DataGateway\Worker.cs:line 28 at UnivarQ.DataGateway.SensitivityCustomerWorker.SaveSensitivityCustomer(SensitivityCustomerEntity sensCust, List1 csPriceGroupIdsToDelete, List1 csItemGroupIdsToDelete, List1 csProductFamilyIdsToDelete, Boolean refetch) in C:\Projects\UnivarQ\Current\Product\Production\Facade\DataGateway\SensitivityCustomerWorker.cs:line 46 at UnivarQ.LogicManagers.Quoting.SensitivityCreator.CreateCustomerSensitivities(SensitivityCustomerEntity sensCust, QuoteEntity quote) in C:\Projects\UnivarQ\Current\Product\Production\Facade\LogicManagers\Quoting\SensitivityCreator.cs:line 36 at UnivarQ.LogicManagers.Quoting.QuoteProcessor.ProcessManualQuote(SensitivityCustomerEntity sensCust, QuoteEntity quoteEntity) in C:\Projects\UnivarQ\Current\Product\Production\Facade\LogicManagers\Quoting\QuoteProcessor.cs:line 54 at UnivarQ.LogicManagers.Quoting.QuoteProcessor.ProcessQuote(QuoteEntity quoteEntity, Boolean isManualQuote) in C:\Projects\UnivarQ\Current\Product\Production\Facade\LogicManagers\Quoting\QuoteProcessor.cs:line 37 at UnivarQ.LogicManagers.Quoting.QuoteProcessor.ProcessManualQuotes(EntityCollection1 quoteCollection) in C:\Projects\UnivarQ\Current\Product\Production\Facade\LogicManagers\Quoting\QuoteProcessor.cs:line 29 at UnivarQ.LogicManagers.Quoting.QuoteSubmitter.SendQuote(QuoteEntity quoteEntity, List1 quoteProductIdsToDelete, List1 volumeBreakIdsToDelete, List1 customerIdListToNotInclude) in C:\Projects\UnivarQ\Current\Product\Production\Facade\LogicManagers\Quoting\QuoteSubmitter.cs:line 50 at UnivarQ.QService.UnivarQService.SendQuote(QuoteEntity quoteEntity, List1 quoteProductIdsToDelete, List1 volumeBreakIdsToDelete, List`1 customerIdList) in C:\Projects\UnivarQ\Current\Product\Production\Services\QService\UnivarQService.cs:line 833 at SyncInvokeSendQuote(Object , Object[] , Object[] ) at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs) at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc) at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)

In the above code each of the entities starting with Sensitivity... inherit from SensitivityEntity. I can supply the SQL Output if that would help.

I'm very puzzled by this because it seems to me to be quite a simple scenario - fetch an entity, add children, add children to the children, etc., set root entity to dirty, do recursive save. Any help will be much appreciated.

Walaa avatar
Walaa
Support Team
Posts: 14946
Joined: 21-Aug-2005
# Posted on: 01-May-2008 17:09:38   

When debugging I'm getting a ORMConcurrencyException when recursively saving a hierarchy. Each of the entities in the hierarchy inherit from the same base class, SensitivityEntity.

Just to make sure I understand you correctly, you mean you are saving a collection of entities of type SensitivityEntity (Inheritance hierarchy), and recursively you are saving their related entities (graphs), correct?

Is the above mentiones Hierarchy a "Traget Per Entity" or a "Target Per Hierarchy"?

I don't see a reason for setting the IsDirty flag, try not to use it.

ORMConcurrencyException. This exception can be thrown in two situations: 1- During a save of one or more entities. When, during a save action, a save fails, i.e. doesn't affect any rows the exception will be thrown. This can be caused by the fact that the row being updated is already deleted, or the predicate created by the set

Would you please inspect the generated SQL queries and try to execute them manually against the database to trace the issue.

2- The exception can be thrown also if ConcurrencyPredicateFactory or the passed in predicate caused a failure of the update due to a concurrency violation. The exception will terminate the transaction started during a recursive save and will therefore make a recursive save action completely atomic

Are you using Concurrency control?

saggett
User
Posts: 50
Joined: 12-Nov-2007
# Posted on: 01-May-2008 17:19:31   

I'm doing a recursive save on a single SensitivityCustomerEntity, which has a collection of SensitivityProductFamilyEntity, each of which has a collection of SensitivityItemGroup, each of which has a collection of SensitivityPriceGroupEntity. In this case, under the root entity, SensitivityCustomerEntity, there's just one new SensitivityProductFamilyEntity, which has one new SensitivityItemGroupEntity, which has one new SensitivityPriceGroupEntity.

I'm using Target Per Entity.

Everything goes well with the inserts, but then it generates a update query for the root entity which fails before that db query is executed. So I get:

Method Enter: CreateInsertDQ
Method Enter: CreateSingleTargetInsertDQ
Generated Sql query: 
    Query: INSERT INTO [dbo].[Sensitivity] ([SensitivityTypeId], [CustomerProfileTypeId], [TimePeriod], [ExpiryPeriod], [IsActive], [EmailAddress])  VALUES (@SensitivityTypeId, @CustomerProfileTypeId, @TimePeriod, @ExpiryPeriod, @IsActive, @EmailAddress);SELECT @Id_SensitivityEntity=SCOPE_IDENTITY()
    Parameter: @Id_SensitivityEntity : Int32. Length: 0. Precision: 10. Scale: 0. Direction: Output. Value: <undefined value>.
    Parameter: @SensitivityTypeId : Int32. Length: 0. Precision: 10. Scale: 0. Direction: Input. Value: 1.
    Parameter: @CustomerProfileTypeId : Int32. Length: 0. Precision: 10. Scale: 0. Direction: Input. Value: 1.
    Parameter: @TimePeriod : Int32. Length: 0. Precision: 10. Scale: 0. Direction: Input. Value: 3.
    Parameter: @ExpiryPeriod : Int32. Length: 0. Precision: 10. Scale: 0. Direction: Input. Value: 3.
    Parameter: @IsActive : Boolean. Length: 0. Precision: 0. Scale: 0. Direction: Input. Value: True.
    Parameter: @EmailAddress : AnsiString. Length: 50. Precision: 0. Scale: 0. Direction: Input. Value: "Qtest@dseurope.com".


Method Exit: CreateSingleTargetInsertDQ
Method Enter: CreateSingleTargetInsertDQ
Generated Sql query: 
    Query: INSERT INTO [dbo].[SensitivityProductFamily] ([Id], [ProductFamilyId], [SensitivityCustomerId])  VALUES (@Id, @ProductFamilyId, @SensitivityCustomerId)
    Parameter: @Id : Int32. Length: 0. Precision: 10. Scale: 0. Direction: Input. Value: <undefined value>.
    Parameter: @ProductFamilyId : Int32. Length: 0. Precision: 10. Scale: 0. Direction: Input. Value: 5.
    Parameter: @SensitivityCustomerId : Int32. Length: 0. Precision: 10. Scale: 0. Direction: Input. Value: 12451.


Method Exit: CreateSingleTargetInsertDQ
Method Exit: CreateInsertDQ
Method Enter: CreatePagingSelectDQ
Method Enter: CreateSelectDQ
Method Enter: CreateSelectDQ
Generated Sql query: 
    Query: SELECT [dbo].[Sensitivity].[Id] AS [Id_SensitivityEntity], [dbo].[Sensitivity].[SensitivityTypeId], [dbo].[Sensitivity].[CustomerProfileTypeId], [dbo].[Sensitivity].[TimePeriod], [dbo].[Sensitivity].[ExpiryPeriod], [dbo].[Sensitivity].[IsActive], [dbo].[Sensitivity].[Name], [dbo].[Sensitivity].[EmailAddress], [dbo].[SensitivityProductFamily].[Id], [dbo].[SensitivityProductFamily].[ProductFamilyId], [dbo].[SensitivityProductFamily].[SensitivityCustomerId] FROM ( [dbo].[Sensitivity]  INNER JOIN [dbo].[SensitivityProductFamily]  ON  [dbo].[Sensitivity].[Id]=[dbo].[SensitivityProductFamily].[Id]) WHERE ( ( [dbo].[Sensitivity].[Id] = @Id_SensitivityEntity1))
    Parameter: @Id_SensitivityEntity1 : Int32. Length: 0. Precision: 10. Scale: 0. Direction: Input. Value: 18477.

Method Exit: CreateSelectDQ
Method Exit: CreatePagingSelectDQ: no paging.
Method Enter: CreateInsertDQ
Method Enter: CreateSingleTargetInsertDQ
Generated Sql query: 
    Query: INSERT INTO [dbo].[Sensitivity] ([SensitivityTypeId], [CustomerProfileTypeId], [TimePeriod], [ExpiryPeriod], [IsActive], [EmailAddress])  VALUES (@SensitivityTypeId, @CustomerProfileTypeId, @TimePeriod, @ExpiryPeriod, @IsActive, @EmailAddress);SELECT @Id_SensitivityEntity=SCOPE_IDENTITY()
    Parameter: @Id_SensitivityEntity : Int32. Length: 0. Precision: 10. Scale: 0. Direction: Output. Value: <undefined value>.
    Parameter: @SensitivityTypeId : Int32. Length: 0. Precision: 10. Scale: 0. Direction: Input. Value: 1.
    Parameter: @CustomerProfileTypeId : Int32. Length: 0. Precision: 10. Scale: 0. Direction: Input. Value: 1.
    Parameter: @TimePeriod : Int32. Length: 0. Precision: 10. Scale: 0. Direction: Input. Value: 3.
    Parameter: @ExpiryPeriod : Int32. Length: 0. Precision: 10. Scale: 0. Direction: Input. Value: 3.
    Parameter: @IsActive : Boolean. Length: 0. Precision: 0. Scale: 0. Direction: Input. Value: True.
    Parameter: @EmailAddress : AnsiString. Length: 50. Precision: 0. Scale: 0. Direction: Input. Value: "Qtest@dseurope.com".


Method Exit: CreateSingleTargetInsertDQ
Method Enter: CreateSingleTargetInsertDQ
Generated Sql query: 
    Query: INSERT INTO [dbo].[SensitivityItemGroup] ([Id], [ItemGroupId], [SensitivityProductFamilyId])  VALUES (@Id, @ItemGroupId, @SensitivityProductFamilyId)
    Parameter: @Id : Int32. Length: 0. Precision: 10. Scale: 0. Direction: Input. Value: <undefined value>.
    Parameter: @ItemGroupId : Int32. Length: 0. Precision: 10. Scale: 0. Direction: Input. Value: 310.
    Parameter: @SensitivityProductFamilyId : Int32. Length: 0. Precision: 10. Scale: 0. Direction: Input. Value: 18477.


Method Exit: CreateSingleTargetInsertDQ
Method Exit: CreateInsertDQ
Method Enter: CreatePagingSelectDQ
Method Enter: CreateSelectDQ
Method Enter: CreateSelectDQ
Generated Sql query: 
    Query: SELECT [dbo].[Sensitivity].[Id] AS [Id_SensitivityEntity], [dbo].[Sensitivity].[SensitivityTypeId], [dbo].[Sensitivity].[CustomerProfileTypeId], [dbo].[Sensitivity].[TimePeriod], [dbo].[Sensitivity].[ExpiryPeriod], [dbo].[Sensitivity].[IsActive], [dbo].[Sensitivity].[Name], [dbo].[Sensitivity].[EmailAddress], [dbo].[SensitivityItemGroup].[Id], [dbo].[SensitivityItemGroup].[ItemGroupId], [dbo].[SensitivityItemGroup].[SensitivityProductFamilyId] FROM ( [dbo].[Sensitivity]  INNER JOIN [dbo].[SensitivityItemGroup]  ON  [dbo].[Sensitivity].[Id]=[dbo].[SensitivityItemGroup].[Id]) WHERE ( ( [dbo].[Sensitivity].[Id] = @Id_SensitivityEntity1))
    Parameter: @Id_SensitivityEntity1 : Int32. Length: 0. Precision: 10. Scale: 0. Direction: Input. Value: 18478.

Method Exit: CreateSelectDQ
Method Exit: CreatePagingSelectDQ: no paging.
Method Enter: CreateInsertDQ
Method Enter: CreateSingleTargetInsertDQ
Generated Sql query: 
    Query: INSERT INTO [dbo].[Sensitivity] ([SensitivityTypeId], [CustomerProfileTypeId], [TimePeriod], [ExpiryPeriod], [IsActive], [EmailAddress])  VALUES (@SensitivityTypeId, @CustomerProfileTypeId, @TimePeriod, @ExpiryPeriod, @IsActive, @EmailAddress);SELECT @Id_SensitivityEntity=SCOPE_IDENTITY()
    Parameter: @Id_SensitivityEntity : Int32. Length: 0. Precision: 10. Scale: 0. Direction: Output. Value: <undefined value>.
    Parameter: @SensitivityTypeId : Int32. Length: 0. Precision: 10. Scale: 0. Direction: Input. Value: 1.
    Parameter: @CustomerProfileTypeId : Int32. Length: 0. Precision: 10. Scale: 0. Direction: Input. Value: 1.
    Parameter: @TimePeriod : Int32. Length: 0. Precision: 10. Scale: 0. Direction: Input. Value: 3.
    Parameter: @ExpiryPeriod : Int32. Length: 0. Precision: 10. Scale: 0. Direction: Input. Value: 3.
    Parameter: @IsActive : Boolean. Length: 0. Precision: 0. Scale: 0. Direction: Input. Value: True.
    Parameter: @EmailAddress : AnsiString. Length: 50. Precision: 0. Scale: 0. Direction: Input. Value: "Qtest@dseurope.com".


Method Exit: CreateSingleTargetInsertDQ
Method Enter: CreateSingleTargetInsertDQ
Generated Sql query: 
    Query: INSERT INTO [dbo].[SensitivityPriceGroup] ([Id], [PriceGroupId], [SensitivityItemGroupId])  VALUES (@Id, @PriceGroupId, @SensitivityItemGroupId)
    Parameter: @Id : Int32. Length: 0. Precision: 10. Scale: 0. Direction: Input. Value: <undefined value>.
    Parameter: @PriceGroupId : Int32. Length: 0. Precision: 10. Scale: 0. Direction: Input. Value: 7335.
    Parameter: @SensitivityItemGroupId : Int32. Length: 0. Precision: 10. Scale: 0. Direction: Input. Value: 18478.


Method Exit: CreateSingleTargetInsertDQ
Method Exit: CreateInsertDQ
Method Enter: CreatePagingSelectDQ
Method Enter: CreateSelectDQ
Method Enter: CreateSelectDQ
Generated Sql query: 
    Query: SELECT [dbo].[Sensitivity].[Id] AS [Id_SensitivityEntity], [dbo].[Sensitivity].[SensitivityTypeId], [dbo].[Sensitivity].[CustomerProfileTypeId], [dbo].[Sensitivity].[TimePeriod], [dbo].[Sensitivity].[ExpiryPeriod], [dbo].[Sensitivity].[IsActive], [dbo].[Sensitivity].[Name], [dbo].[Sensitivity].[EmailAddress], [dbo].[SensitivityPriceGroup].[Id], [dbo].[SensitivityPriceGroup].[PriceGroupId], [dbo].[SensitivityPriceGroup].[SensitivityItemGroupId] FROM ( [dbo].[Sensitivity]  INNER JOIN [dbo].[SensitivityPriceGroup]  ON  [dbo].[Sensitivity].[Id]=[dbo].[SensitivityPriceGroup].[Id]) WHERE ( ( [dbo].[Sensitivity].[Id] = @Id_SensitivityEntity1))
    Parameter: @Id_SensitivityEntity1 : Int32. Length: 0. Precision: 10. Scale: 0. Direction: Input. Value: 18479.

Method Exit: CreateSelectDQ
Method Exit: CreatePagingSelectDQ: no paging.
Method Enter: CreateUpdateDQ(4)
Method Enter: CreateSingleTargetUpdateDQ(4)
Method Enter: CreateSingleTargetUpdateDQ(4)
Method Exit: CreateUpdateDQ(4)

saggett
User
Posts: 50
Joined: 12-Nov-2007
# Posted on: 01-May-2008 17:19:46   

I'm not using concurrency control.

Walaa avatar
Walaa
Support Team
Posts: 14946
Joined: 21-Aug-2005
# Posted on: 02-May-2008 10:58:34   

Everything goes well with the inserts, but then it generates a update query for the root entity which fails before that db query is executed. So I get:

Does the root entity need to be updated? does it have any changed fields values?

Anyway would you please comment the "IsDirty = true" lines. And the recursive save should be taking place too.

saggett
User
Posts: 50
Joined: 12-Nov-2007
# Posted on: 02-May-2008 11:07:32   

Commented the IsDirty lines out and it worked. But it was my understanding that if you have a clean object with dirty children, and then do a recursive save on it, nothing will happen because the LLBLGen code checks the IsDirty on the rootEntity, finds it to be false, then cancels the save.

So say you have a customer ... order ... order detail, with one dirty order detail, what should you do to carry out a successful recursive save on customer, with no queries done with respect to customer and order and one update query for the order detail? Set the Customer.IsDirty to true, or does the LLBLGen code now do recursive saves even when the root entity is clean?

Walaa avatar
Walaa
Support Team
Posts: 14946
Joined: 21-Aug-2005
# Posted on: 02-May-2008 11:42:24   

IsDirty only determines if this entity is going to be saved or not, but it doesn't determine if the attached graph of entities is going to be recursively saved or not. (this is only determined by the recurse flag).

In other words you shouldn't set the IsDirty flag.