Find the Changed Row in a Dataset - Update BPM

Is there a way to find the changed row in Update Method Directive.

I want to set a field value on the Header table regardless of the child table being updated. Is there traverse the ds to find the first Updated row? I really just need to grab the key field from the changed row to make everything work, but it seems like I have to look through each child table for a RowMod to do this?

With LINQ you can do:

var updatedRow = ds.Where(x => x.RowMod == "U").FirstOrDefault();

if(updatedRow != null)
{
  //your code here, like
  var orderNum = updatedRow.OrderNum;
}


Edited to add:
If you need one of the child datasets, you can reference it in the query, i.e.:

var updatedRow = ds.OrderDtl.Where(x => x.RowMod == "U").FirstOrDefault();
1 Like

I don’t think you can use LINQ directly on the ds (Tableset) parameter, unfortunately. I think there’s a way to do this like you’re asking, but I think it might be a little too inefficient to just stick on an update method with no prior conditions. If a BO is calling this BPM on every update, I think it’s going to slow the whole BO down significantly.

I think a better method would be to create a function with request parameters for the value you want to add, and the Primary Key for the header table (OrderNum, PONum, whichever table you’re using), and call the BO to update that header. Then call that function from Data Directives on each of the child tables. It would be more work to maintain the multiple BPMs, but it would keep the overhead on executing the BPM down, and it would execute after the update, so it shouldn’t slow the process down as much.

If you DO need to do it the way you described, by looping through each child table during the Update method, you should be able to do that by converting ds to a generic DataSet. If you put it in a conditional widget with custom code, this should work:

/*
     You might need to add the Epicor.ServiceModel Assembly
*/


// Convert Tableset to System.Data.DataSet
var dsDataSet = DatasetAdapter.ConvertToGenericDataset( ds, "", null, true );


// Loop Through Tables
foreach ( DataTable table in dsDataSet.Tables )
{
    //Table to Enumerable so you can use LINQ
    var myValue = table.AsEnumerable() 
                       .Where( x => x.Field<string>("RowMod") == "U" )
                       .Select( s => s.Field<string>("KeyValueField_c") )
                       .FirstOrDefault();

    if ( myValue != null )
    {
        MyKeyValue = myValue; // MyKeyValue BPM variable
        return true; // Escape Conditional Code Block when Updated Row is found
    }
}

return false;
2 Likes