How to delete editable child from editable root

How to delete editable child from editable root

Old forum URL: forums.lhotka.net/forums/t/11911.aspx


c_manboy posted on Thursday, March 28, 2013

I have an editable root object which contains an editable child.  I would like to detete the editable child but I receive an error stating "Can not directly mark a child object for deletion - use its parent collection".   The child is not part of a collection.

RockfordLhotka replied on Saturday, March 30, 2013

Cast the child object to IEditableBusinessObject from Csla.Core and use the DeleteChild method.

c_manboy replied on Wednesday, April 17, 2013

When I delete the child object, it deletes it from the database, but fails to null the property on the parent.   Instead, it marks the child as new.  Do I have to manually null the property after deletion?

I overrode child changed on my root object:

        Protected Overrides Sub OnChildChanged(e As Core.ChildChangedEventArgs)
            If e.PropertyChangedArgs IsNot Nothing Then
                Console.WriteLine(e.ChildObject.ToString & ": " & e.PropertyChangedArgs.PropertyName)
            End If          
             MyBase.OnChildChanged(e)
         End Sub

When I delete the object on the UI, it generates:

HCM.Library.EntityPerson: IsDeleted
HCM.Library.EntityPerson:
HCM.Library.EntityPerson: IsSelfDirty
HCM.Library.EntityPerson: IsDirty
HCM.Library.EntityPerson: IsSavable

And then when I do a beginsave on the viewmodel it generates:

HCM.Library.EntityPerson: IsNew
HCM.Library.EntityPerson: IsDeleted
HCM.Library.EntityPerson:

I put a breakpoint in my root DP and the IsNew change occurs immediately following the FieldManager.Update(me).

My root object child property:

       Private Shared ReadOnly _entityPersonProperty As PropertyInfo(Of EntityPerson) =
            RegisterProperty(Of EntityPerson)(Function(p As Entity) p.EntityPerson, Csla.RelationshipTypes.Child)
        Public ReadOnly Property EntityPerson() As EntityPerson
            Get
                If Not (FieldManager.FieldExists(_entityPersonProperty)) Then
                    Dim criteria As New HCM.Library.EntityPersonCriteria()
                    criteria.EntityId = Identification
                    If (HCM.Library.EntityPerson.Exists(criteria)) Then
                        LoadProperty(_entityPersonProperty, HCM.Library.EntityPerson.GetByEntityIdChild(Identification))
                    End If
                End If
                Return GetProperty(_entityPersonProperty)
            End Get
        End Property

 My child DP:

        Private Sub Child_DeleteSelf()
            DataPortal_Delete(New EntityPersonCriteria(EntityId))
        End Sub
        <Transactional(TransactionalTypes.TransactionScope)> _
        Protected Shadows Sub DataPortal_Delete(ByVal criteria As EntityPersonCriteria)
            FieldManager.UpdateChildren(Me)
	   Using df = DalFactory.GetDalManager
               Dim DataAccess = df.GetProvider(of IEntityPersonDal)()
	      DataAccess.Delete(criteria)     	
            End Using
        End Sub

 

c_manboy replied on Wednesday, April 17, 2013

Well, my problem appears to be by design.  I found this in the ChildDataPortal source which marks a child object as new after it is deleted:

          if (busObj.IsDeleted)
          {
            if (!busObj.IsNew)
            {
              // tell the object to delete itself
              lb.CallMethod("Child_DeleteSelf", parameters);
            }
            if (target != null)
              target.MarkNew();
            else
              lb.CallMethodIfImplemented("MarkNew");

          }

I'm hoping it's a bug, but guessing that I'm doing something wrong.

c_manboy replied on Wednesday, April 17, 2013

Ok, I added this to my child delete dp after the db call, and it works as expected:

            Dim parent = TryCast(Me.Parent, IParent)
            If parent IsNot Nothing Then
                parent.RemoveChild(Me)
            End If

However, I would appreciate it if someone could confirm that this is the correct way.

Thanks!

 

Copyright (c) Marimer LLC