Skip to main content
Solved

Cascading Delete [PXParent] does not work


Forum|alt.badge.img
  • Jr Varsity III
  • 23 replies

I have a DAC MySOInfo defined as Child of SOOrder and another DAC MySODetail as Child of MySOInfo.

If a SOOrder is deleted in Screen SO301000, I would expect that the linked MySOInfo entries are deleted and MySODetail entries, too. In fact the first Children MySOInfo are deleted but the Children’s Children MySODetail are not deleted.

The DAC’s are defined like this:

  [Serializable]
    [PXCacheName("MySOInfo")]
    public class MySOInfo : IBqlTable
    {
        #region RecordID
        [PXDBIdentity(IsKey = true)]
        public virtual int? RecordId { get; set; }
        public abstract class recordId : PX.Data.BQL.BqlInt.Field<recordId> { }
        #endregion

        #region OrderNbr
        [PXParent(typeof(SelectFrom<SOOrder>.Where<SOOrder.orderNbr.IsEqual<orderNbr>
                                              .And<SOOrder.orderType.IsEqual<orderType>>>))]
        [PXDBString(15, IsUnicode = true, InputMask = "")]
        [PXUIField(DisplayName = "Order Nbr")]
        public virtual string OrderNbr { get; set; }
        public abstract class orderNbr : PX.Data.BQL.BqlString.Field<orderNbr> { }
        #endregion

        #region OrderType
        [PXDBString(2, IsFixed = true, InputMask = "")]
        [PXUIField(DisplayName = "Order Type")]
        public virtual string OrderType { get; set; }
        public abstract class orderType : PX.Data.BQL.BqlString.Field<orderType> { }
        #endregion
....
    }


    [Serializable]
    [PXCacheName("MySODetail")]
    public class MySODetail : IBqlTable
    {
        #region BaseRecordID
 [PXParent(typeof(SelectFrom<MySOInfo>.Where<MySOInfo.recordId.IsEqual<baseRecordID>>))]
        [PXDBInt(IsKey = true)]
        public virtual int? BaseRecordID { get; set; }
        public abstract class baseRecordID : PX.Data.BQL.BqlInt.Field<baseRecordID> { }
        #endregion
...
    }

What do I have to do to have the Children’s Children deleted as well.

Best answer by Naveen Boga

Yes… that is correct!! 

To work with cascading deletion we need to have a views declaration in that particular graph. Even we are using or not we need to create dummy views to work with cascading deletion….

View original
Did this topic help you find an answer to your question?

10 replies

Gabriel Michaud
Captain II
Forum|alt.badge.img+10

Your are missing .FromCurrent in your PXParent attribute declarations. It should look like:

 [PXParent(typeof(SelectFrom<MySOInfo>.Where<MySOInfo.recordId.IsEqual<baseRecordID.FromCurrent>>))]

The same issue exists with your other DAC.

Note that I would strongly recommend adding OrderType before OrderNbr -- the SOOrder table has a composite primary key, and beside the risk of the same order nbr. being present in different order types, this will negatively affect performance since SQL will not be able to fully used the clustered index that exist.


Forum|alt.badge.img
  • Author
  • Jr Varsity III
  • 23 replies
  • June 10, 2021

Thank you for the very fast reply @Gabriel Michaud .

Adding .FromCurrent makes no difference.

 

Any more ideas?


Naveen Boga
Captain II
Forum|alt.badge.img+19
  • Captain II
  • 3377 replies
  • June 10, 2021

Hi @mhaps ,

You just need to add the PXParent attribute and DBDefault for the Child DAC MySODetail …

Please find the example below..

 

[Serializable]
    [PXCacheName("MySODetail")]
    public class MySODetail : IBqlTable
    {
        #region BaseRecordID
	   [PXParent(typeof(Select<MySOInfo, Where<MySOInfo.recordId, Equal<Current<MySODetail.baseRecordID>>>>))]
        [PXDBInt(IsKey = true)]  

		[PXDBDefault(typeof(MySOInfo.recordId))]
        public virtual int? BaseRecordID { get; set; }
        public abstract class baseRecordID : PX.Data.BQL.BqlInt.Field<baseRecordID> { }
        #endregion
...
    }

 

Hope this helps!!


Naveen Boga
Captain II
Forum|alt.badge.img+19
  • Captain II
  • 3377 replies
  • June 10, 2021

Forum|alt.badge.img
  • Author
  • Jr Varsity III
  • 23 replies
  • June 11, 2021

I created a Graph for the first level Child MySOInfo. If I delete MySOInfo entries from this graph, the MySODetail entries are deleted. So the both master/detail relationships seem to be ok.

It is just the Cascading delete that does not work.Only the direct Children are deleted, not the Children’s Children.


Naveen Boga
Captain II
Forum|alt.badge.img+19
  • Captain II
  • 3377 replies
  • June 11, 2021

@mhaps,

Sorry, I’m bit confused….In your requirement do you have 3 DAC file? (you have given only 2 DAC files bro)

Parent DAC  → Parent Child DAC → Child’s Child DAC ?

When your deleting the Parent DAC, then you need to delete the “Parent Child DAC” records and “Child’s Child DAC” records right?

if yes, can you please provide the 3 DAC files here?  

 


Forum|alt.badge.img
  • Author
  • Jr Varsity III
  • 23 replies
  • June 11, 2021

Yes 3 DAC’s. The missing one is the native SOOrder.

SOOrder → MySOInfo → MySODetail

When an SOOrder is deleted in SO301000, MySOInfo and MySODetail should be deleted, too


Naveen Boga
Captain II
Forum|alt.badge.img+19
  • Captain II
  • 3377 replies
  • June 11, 2021

@maps Can you please try with below code and verify..

 

[Serializable]
    [PXCacheName("MySOInfo")]
    public class MySOInfo : IBqlTable
    {
        #region RecordID
        [PXDBIdentity(IsKey = true)]
        public virtual int? RecordId { get; set; }
        public abstract class recordId : PX.Data.BQL.BqlInt.Field<recordId> { }
        #endregion

        #region OrderNbr
		[PXDBString(15, IsUnicode = true, InputMask = "")]
        //[PXParent(typeof(SelectFrom<SOOrder>.Where<SOOrder.orderNbr.IsEqual<orderNbr>
         //.And<SOOrder.orderType.IsEqual<orderType>>>))]

		[PXParent(typeof(Select<SOOrder, Where<SOOrder.orderType, Equal<Current<MySOInfo.orderType>>,
				And<SOOrder.OrderNbr, Equal<Current<MySOInfo.OrderNbr>>>>>))]       

		[PXDBDefault(typeof(SOOrder.orderNbr))]        
        [PXUIField(DisplayName = "Order Nbr")]
        public virtual string OrderNbr { get; set; }
        public abstract class orderNbr : PX.Data.BQL.BqlString.Field<orderNbr> { }
        #endregion

        #region OrderType
        [PXDBString(2, IsFixed = true, InputMask = "")]
        [PXUIField(DisplayName = "Order Type")]
        public virtual string OrderType { get; set; }
        public abstract class orderType : PX.Data.BQL.BqlString.Field<orderType> { }
        #endregion
....
    }

	[Serializable]
    [PXCacheName("MySODetail")]
    public class MySODetail : IBqlTable
    {
        #region BaseRecordID

        [PXDBInt(IsKey = true)]
		[PXParent(typeof(Select<MySOInfo, Where<MySOInfo.recordId, Equal<Current<MySODetail.baseRecordID>>>>))]
      	[PXDBDefault(typeof(MySOInfo.recordId))]
        public virtual int? BaseRecordID { get; set; }
        public abstract class baseRecordID : PX.Data.BQL.BqlInt.Field<baseRecordID> { }
        #endregion
...
    }


Forum|alt.badge.img
  • Author
  • Jr Varsity III
  • 23 replies
  • June 11, 2021

Finally I found it out, or at least a workaround.

I make use of MySOInfo in an extension of SOOrderEntity, where the delete action is executed. MySODetail is not used in this graph. There is another graph for MySOInfo and MySODetail.

Now I’ve added an unsed view of MySODetail in the SOOrderEntity extension graph and violá MySODetail entries are deleted.

 

I don’t like this unused view but it seems that the master-detail relation in the DAC classes are not sufficient for cascading delete.


Naveen Boga
Captain II
Forum|alt.badge.img+19
  • Captain II
  • 3377 replies
  • Answer
  • June 11, 2021

Yes… that is correct!! 

To work with cascading deletion we need to have a views declaration in that particular graph. Even we are using or not we need to create dummy views to work with cascading deletion….


Reply


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings