Skip to main content
Solved

What does Search do differently than PK.Find?


Forum|alt.badge.img+5

I seem to be getting caught more and more by this.  I have this line of code:

orderGraph.Document.Current = orderGraph.Document.Search<SOOrder.orderType, SOOrder.orderNbr>(graphBulk.Order.Current.OrderType, graphBulk.Order.Current.OrderNbr);

I believe it should be looking for a sales order record. It worked fine in testing with SO for the order type.  Then we added another order type, BK, and this code failed to find the record.

So I switched the code to this:

SOOrder order = SOOrder.PK.Find(graphBulk, graphBulk.Order.Current.OrderType, graphBulk.Order.Current.OrderNbr);

And it finds the record without a problem.

So what is the Search method doing that causes it not to find the record?  Sometimes I will need to use a search but I need to be able to understand why it operates differently (and cannot find the SO record when I’ve supplied both key field values).

Best answer by Yuriy Zaletskyy

Main purpose of Search, is to find object and load cache of found primary DAC class and dependable views. While Find does what it says: finds object in DB by provided keys. So if you need to find single object, use Find. If you want graph trip imitate opening oof item which mimics UI opening, use search

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

4 replies

Yuriy Zaletskyy
Jr Varsity I
Forum|alt.badge.img+3

The Search method in Acumatica is a generic method that can be used to search for a record in any DAC (Data Access Class) based on the specified criteria. It takes two arguments: the first is the field that you want to search on, and the second is the value you are searching for. In the first line of code you provided, it is searching for a sales order (SOOrder) record based on the OrderType and OrderNbr fields. However, it seems that when you added a new order type BK, the Search method was not able to find the corresponding record.

On the other hand, the PK.Find method is a specific method that is used to search for a record in a DAC based on its primary key fields. It takes three arguments: the first is the current graph, the second is the primary key field and the third is the primary key value. In the second line of code you provided, it is also searching for a sales order record but it uses the primary key fields to retrieve the record.

It is likely that the Search method was not able to find the record because the new order type BK does not have the same primary key fields as the SO order type and hence the Search method was not able to find the record with the supplied key fields. On the other hand, PK.Find method uses the primary key fields to search for the record, which is why it was able to find the record without a problem.


Forum|alt.badge.img+5
  • Author
  • Captain II
  • 508 replies
  • January 21, 2023

Thank you, Yuriy.  That helped.  I dug into the documentation a little further and looked at the Acumatica source code.  Most of the time Search is performed on a single field:

ARInvoice invoice = Document.Current;
SOInvoiceEntry graph = CreateInstance<SOInvoiceEntry>();
graph.Document.Current = graph.Document.Search<ARInvoice.refNbr>(invoice.RefNbr, invoice.DocType);

The above will use SOInvoiceEntry to locate an ARInvoice record for a given refNbr and order the results in DocType order.

But when you search on two fields, like I was, you need to include a PXGraph for the first parameter. So I think that this code is the correct version of what I first tried:

orderGraph.Document.Current = orderGraph.Document.Search<SOOrder.orderType, SOOrder.orderNbr>(this, graphBulk.Order.Current.OrderType, graphBulk.Order.Current.OrderNbr);

Or this should work as well (which I see plenty of examples of in the Acumatica code):

orderGraph.Document.Current = orderGraph.Document.Search<SOOrder.orderNbr>(graphBulk.Order.Current.OrderNbr);

Forum|alt.badge.img+5
  • Author
  • Captain II
  • 508 replies
  • January 21, 2023

Hmmm…  I found this line in CADepositEntry that would argue that my first attempt was still correct:

if (this.Details.Search<CADepositDetail.origModule, CADepositDetail.origDocType, CADepositDetail.origRefNbr>(BatchModule.AR, ARPaymentType.GetVoidingARDocType(pmt.DocType), pmt.RefNbr).Count == 0)

Three fields and three values to search for - no graph required.

And this example - two search fields and two values to search for:

graph.Header.Current = graph.Header.Search<CABankTranHeader.cashAccountID, CABankTranHeader.refNbr>(iStatement.CashAccountID, iStatement.RefNbr);

 


Yuriy Zaletskyy
Jr Varsity I
Forum|alt.badge.img+3

Main purpose of Search, is to find object and load cache of found primary DAC class and dependable views. While Find does what it says: finds object in DB by provided keys. So if you need to find single object, use Find. If you want graph trip imitate opening oof item which mimics UI opening, use search


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