Skip to main content
Answer

Can I use PXForeignReference on a DAC extension to ensure data integrity?

  • January 24, 2024
  • 6 replies
  • 234 views

darylbowman
Captain II
Forum|alt.badge.img+15

I am attempting to use PXForeignReference on a DAC extension to ensure the field is set to null when the referenced document is deleted. It published fine but doesn’t work. Is this possible?

(NOTE: at the moment, ReferenceBehavior is ‘Restrict’ which should throw an exception upon deleting)

public class DSDPMCostBudget_Ext : PXCacheExtension<PX.Objects.PM.PMCostBudget>
{
public static bool IsActive() => true;

#region UsrPDPOType
[PXDBString(2, IsUnicode = true)]
[POOrderType.List()]
[PXDefault(POOrderType.ProjectDropShip, PersistingCheck = PXPersistingCheck.Nothing)]
[PXUIField(DisplayName = "PO Type")]
public virtual string UsrPDPOType { get; set; }
public abstract class usrPDPOType : BqlString.Field<usrPDPOType> { }
#endregion

#region UsrPDPONbr
[PXDBString(15, IsUnicode = true)]
[PO.RefNbr(typeof(Search2<POOrder.orderNbr,
LeftJoinSingleTable<Vendor, On<POOrder.vendorID, Equal<Vendor.bAccountID>,
And<Match<Vendor, Current<AccessInfo.userName>>>>>,
Where<POOrder.orderType, Equal<Optional<usrPDPOType>>,
And<Vendor.bAccountID, IsNotNull>>,
OrderBy<Desc<POOrder.orderNbr>>>), Filterable = true)]
// Here's the foreign reference
[PXForeignReference(typeof(CompositeKey<
Field<usrPDPOType>.IsRelatedTo<POOrder.orderType>,
Field<usrPDPONbr>.IsRelatedTo<POOrder.orderNbr>>), ReferenceBehavior.Restrict)]
[PXUIField(DisplayName = "PO Nbr")]
public virtual string UsrPDPONbr { get; set; }
public abstract class usrPDPONbr : BqlString.Field<usrPDPONbr> { }
#endregion
}

 

Best answer by darylbowman

Turns out, if I knew how to use foreign references in the first place, it would have been working all along.

I forgot to add [PXReferentialIntegrityCheck] to POOrder.

For the next person, I did that like this, because for whatever reason, you can’t use [PXReferentialIntegrityCheck] with the CacheAttached event.

public class DSDPOOrder_Ext : PXCacheExtension<PX.Objects.PO.POOrder>
{
public static bool IsActive() => true;

#region OrderNbr
[PXMergeAttributes(Method = MergeMethod.Append)]
[PXReferentialIntegrityCheck]
public string OrderNbr { get; set; }
#endregion

}

Thanks @Brian Stevens (source)

6 replies

darylbowman
Captain II
Forum|alt.badge.img+15
  • Author
  • Answer
  • January 24, 2024

Turns out, if I knew how to use foreign references in the first place, it would have been working all along.

I forgot to add [PXReferentialIntegrityCheck] to POOrder.

For the next person, I did that like this, because for whatever reason, you can’t use [PXReferentialIntegrityCheck] with the CacheAttached event.

public class DSDPOOrder_Ext : PXCacheExtension<PX.Objects.PO.POOrder>
{
public static bool IsActive() => true;

#region OrderNbr
[PXMergeAttributes(Method = MergeMethod.Append)]
[PXReferentialIntegrityCheck]
public string OrderNbr { get; set; }
#endregion

}

Thanks @Brian Stevens (source)


Forum|alt.badge.img+4

Turns out, if I knew how to use foreign references in the first place, it would have been working all along.

I forgot to add [PXReferentialIntegrityCheck] to POOrder.

For the next person, I did that like this, because for whatever reason, you can’t use [PXReferentialIntegrityCheck] with the CacheAttached event.

public class DSDPOOrder_Ext : PXCacheExtension<PX.Objects.PO.POOrder>
{
public static bool IsActive() => true;

#region OrderNbr
[PXMergeAttributes(Method = MergeMethod.Append)]
[PXReferentialIntegrityCheck]
public string OrderNbr { get; set; }
#endregion

}

Thanks @Brian Stevens (source)

Glad my blog was able to help.  You may know, but for those that may be wondering “why” for PXReferentialIntegrityCheck on CacheAttached… Keep in mind that CacheAttached is “from within this graph”.  That means, it is basically an optional usage.  Integrity is integrity in season and out of season, so to speak.  As best I can tell, you can’t have integrity “when you feel like it” like within only one specific graph.  You need it in the basic structure of the DAC.  As long as the DAC extension is active in this case, it will apply.  If the DAC isn’t active, the field you want to do an integrity check, for all practical purposes, does not exist.  When it is active, it always must pass the integrity check, always.


darylbowman
Captain II
Forum|alt.badge.img+15
  • Author
  • January 24, 2024

 

...for those that may be wondering “why” for PXReferentialIntegrityCheck on CacheAttached...

That actually makes perfect sense.

So I thought I had solved it, but it turns out, I can only get the error when deleting. I was hoping to set the field to null so it isn’t a broken link. Your blog basically says you didn’t need to go any further in exploring the behavior, so you didn’t.

I don’t suppose you’ve done any more exploring since then?


darylbowman
Captain II
Forum|alt.badge.img+15
  • Author
  • January 24, 2024

So I thought I had solved it

I really hate how many things (recently) are solved by restarting the application.


darylbowman
Captain II
Forum|alt.badge.img+15
  • Author
  • September 19, 2025

I guess it’s the circle of life that has me back here again in 25 R2 for exactly the same project and exactly the same reason. Only, it’s not so easily solved as restarting.


Forum|alt.badge.img+4

 

...for those that may be wondering “why” for PXReferentialIntegrityCheck on CacheAttached...

That actually makes perfect sense.

So I thought I had solved it, but it turns out, I can only get the error when deleting. I was hoping to set the field to null so it isn’t a broken link. Your blog basically says you didn’t need to go any further in exploring the behavior, so you didn’t.

I don’t suppose you’ve done any more exploring since then?

Sorry, Daryl.  When I changed companies, I lost access to my original account until Chris Hackett got me re-linked at Summit.  I totally missed this.  I may be very late to respond, but the short answer is that I have not been down that road in a long time, so I don’t really have any answers for you.