AuditReferenceOfRelatedEntity/AuditDereferenceOfRelatedEntity not symmetrical

Posts   
 
    
yowl
User
Posts: 266
Joined: 11-Feb-2008
# Posted on: 17-Mar-2021 23:00:00   

LLBLGen Framework 5.7/Adapter

Why in AuditDereferenceOfRelatedEntity is the related entity property not null? Take this code where there is a 1:m between ClaimPortEntity and ClaimGradeEntity. The first Assert passes, in AuditReferenceOfRelatedEntity the method is called after the reference is set. The second Assert fails, in AuditDereferenceOfRelatedEntity the related entity is still present. What is the logic behind that, I'd have expected the related entity to be already cleared as the name of the method is AuditDereferenceOfRelatedEntity , and not AuditDereferencingOfRelatedEntity

        [Test]
        public void Unset()
        {
            var claimPort = new ClaimPortEntity();
            var grade = new ClaimGradeEntity();
            claimPort.AuditorToUse = new TestAuditor();
            grade.AuditorToUse = new TestAuditor();

            claimPort.ClaimGrades.Add(grade);


            claimPort.ClaimGrades.Remove(grade);

        }

        class TestAuditor : IAuditor
        {
            public void AuditEntityFieldGet(IEntityCore entity, int fieldIndex)
            {
            }

            public void AuditEntityFieldSet(IEntityCore entity, int fieldIndex, object originalValue)
            {
                throw new NotImplementedException();
            }

            public void AuditDereferenceOfRelatedEntity(IEntityCore entity, IEntityCore relatedEntity, string mappedFieldName)
            {
                Debug.Assert(((ClaimGradeEntity)entity).ClaimPort == null);
            }

            public void AuditReferenceOfRelatedEntity(IEntityCore entity, IEntityCore relatedEntity, string mappedFieldName)
            {
                Debug.Assert(((ClaimGradeEntity)entity).ClaimPort != null);
            }

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 18-Mar-2021 09:27:38   

This is caused by the fact that if you dereference A from B, it's done through A by removing the sync elements on both sides in tandem. If you do grade.ClaimPort =null, it follows the same path as when you do claimPort.ClaimGrades.Remove(grade). As it's not known on one side when the other side removes it (as the code is on the other side) the audit action is called right before the other side's derefencing is being done (which results in the actual set to null).

So it logs the audit action before the action takes place, as that's the only way it can reliably do that in all situations. It's not called ing because that would be in line with similar methods throughout .net which mostly offer a cancel option, and that's not the case here. Your test tests whether our cleanup code works btw, which is a nice gesture but you don't have to do that simple_smile

Frans Bouma | Lead developer LLBLGen Pro
yowl
User
Posts: 266
Joined: 11-Feb-2008
# Posted on: 18-Mar-2021 17:05:49   

Thanks, If the assert is changed to

            public void AuditDereferenceOfRelatedEntity(IEntityCore entity, IEntityCore relatedEntity, string mappedFieldName)
            {
                Debug.Assert(((ClaimGradeEntity)entity).ClaimPort.ClaimGrades.Count == 0);
            }

That also fails, but I think that is expected from what you are saying, I'm not totally sure I understand as neither side appears to be dereferenced when this method is called. I just wrote the test to give something to talk about in this post. I'm happy to close the thread, unless you think the removal from the collection should have occurred.