Why entity is dirty if ...

Posts   
 
    
Meindert
User
Posts: 63
Joined: 07-Nov-2012
# Posted on: 06-Apr-2020 09:57:53   

LLBLGen 5.1.1 DB: MSSQL

In case of an healty entity i like to prefetch some related objects, like below!

Why is the (base) entity dirty ? Is it save to set IsDirty to false? I dont want an unnecessary update because of triggers !


                       prefetchPath.Add(CablesEntity.PrefetchPathCableConfigurations);
                        prefetchPath.Add(CablesEntity.PrefetchPathCableRoutingRoutes);
                        prefetchPath.Add(CablesEntity.PrefetchPathWBSCode);
                        // CableType with dependencies
                        var cbl_type = prefetchPath.Add(CablesEntity.PrefetchPathCableTypes).SubPath;
                        var cbl_conf = cbl_type.Add(CableTypesEntity.PrefetchPathCableConfigurations).SubPath;
                        cbl_conf.Add(CableConfigurationsEntity.PrefetchPathCableShieldings);
                        cbl_conf.Add(CableConfigurationsEntity.PrefetchPathCableWireTypes);
                        // CM from with dependencies
                        var cm1 = prefetchPath.Add(CablesEntity.PrefetchPathControlModule1).SubPath;
                        cm1.Add(ControlModulesEntity.PrefetchPathEquipmentModuleTypeContents);
                        // CM to with dependencies
                        var cm2 = prefetchPath.Add(CablesEntity.PrefetchPathControlModule2).SubPath;
                        cm2.Add(ControlModulesEntity.PrefetchPathEquipmentModuleTypeContents);
                        cm2.Add(ControlModulesEntity.PrefetchPathEquipmentModules);
                        // EMType
                        prefetchPath.Add(CablesEntity.PrefetchPathEquipmentModuleTypeContentCables);

            if (prefetchPath != null)
            {
                using (CoreDataAccessAdapter adapter = CoreDataAccessAdapter.CreateInstance())
                {
                    adapter.FetchEntity(aEntity, prefetchPath);
                    // save and refetch entity if it is dirty
                    adapter.FetchEntity(aEntity);
                    //Globals.SaveChanges(this, aEntity);
                }
            }
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39588
Joined: 17-Aug-2003
# Posted on: 06-Apr-2020 12:02:35   

I think I need more code to see what's going on. E.g. what's 'aEntity', is that a new entity? Please give a concise small example of what you do and what has an unexpected effect. (if you fetch an entity E and related entities, they never should be marked as dirty)

Frans Bouma | Lead developer LLBLGen Pro
Meindert
User
Posts: 63
Joined: 07-Nov-2012
# Posted on: 06-Apr-2020 12:42:29   

I hope this code make sens for you, the results not for me.

when I debug on the compare between DbValue and CurrentValue (object), the debugger doesn't stop on aap=1, but stops on noot=1 When I change the compare in noot = 1 to string compare, instead of object compare, the debugger doesn't stop on both aap=1 and noot=1

The Values of DBValue and CurrentValue are the same! but the entity is Dirty


               // aEntity =  CablesEntity (ID, ...)
               using (CoreDataAccessAdapter adapter = CoreDataAccessAdapter.CreateInstance())
                {
                     adapter.SaveEntity(aEntity);
                    foreach (var field in aEntity.Fields)
                        if (field.DbValue != field.CurrentValue)
                        {
                            int aap = 1;
                        }
                    adapter.FetchEntity(aEntity, prefetchPath);
                    foreach (var field in aEntity.Fields)
                        if (field.DbValue != field.CurrentValue)
                        {
                            int noot = 1;
                        }
                }

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39588
Joined: 17-Aug-2003
# Posted on: 06-Apr-2020 15:28:33   

Can you create a very simple repro? Like is it 1 particular entity that causes this? It's likely a foreign key field (you know which field as you can see that in the debugger), and if so, what is the difference between the field fetched and the field synced?

My guess is that the FK value in aEntity differs only in case with the PK value on the other side. The comparer for when the entity is set will sync the fk with the pk and as the values do differ (on case) the isdirty flag will be set.

But ... it's speculation, you didn't give more info regarding what value the field has in the db, in the entity (DbValue and currentvalue), the value of the PK of the related entity and the FK value in aEntity if you fetch it without a prefetch path.

So example: you have Customer and Order. Customer has a string PK, order has a string FK to customer. I have in Order 1, for CustomerID the value "Foo" and I have a Customer entity with the PK value "FOO". If I then fetch order 1 with a prefetch path that also fetches customer, I get the Customer with Pk FOO but the Fk in Order is 'Foo', it'll be reset to 'FOO' which triggers the change.

At least that's my assumption

Frans Bouma | Lead developer LLBLGen Pro
Meindert
User
Posts: 63
Joined: 07-Nov-2012
# Posted on: 10-Apr-2020 12:48:20   

I have no time at the moment, but use a workaround. After fetch detail with relations I do a simple fetch of the CablesEntity. This works for us.

I did some tests and it seems only to appear for the CablesEntity, also if I fetch details with one simple relation!

Indeed it is only with foreign key fields, all bigint, and as stated before the values are the same, but the object reference not! See also https://www.llblgen.com/tinyforum/GotoMessage.aspx?MessageID=147856&ThreadID=27019

So to be clear below the sequence in case an entiy gets dirty, in this case a CablesEntity: - CablesEntity is made dirty by adding a simple remark (no fk) - Save dirty entity recursive. Now the entity is not dirty. - fetch details with relations. Now entity is dirty again.

Making a simple sample wil not work I'm afraid. Probbaly you like to have code, partial class code, debugging traces, calls to the database or LLBLGen trace tool?!

Walaa avatar
Walaa
Support Team
Posts: 14946
Joined: 21-Aug-2005
# Posted on: 10-Apr-2020 13:07:31   

A sample as in... if you can reproduce this against Northwind database, if not then a small one table DDL script, with couple lines of code, along with the llbkgen project file that's it.

And it's better to check the field. IsDChanged rather than do a comparison of the DBValue and the currentValue, and check on the entity.Fields.IsDirty and the entity.IsChanged property as well.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39588
Joined: 17-Aug-2003
# Posted on: 10-Apr-2020 15:26:58   

Indeed, please check which fields are actually dirty, you know that in the debugger.

And try to reproduce it with just 1 prefetch path node, which one is the one that triggers this? It should be something weird. Also do you share an FK among multiple relationships?

Frans Bouma | Lead developer LLBLGen Pro