Epicor Functions - DB table update

I have a function that is utilizing a custom code widget to update a DB table. I am moving data from a system field to a new UD field because they needed a larger field. (I know I could do this with Business Objects, but in this case, I am potentially updating some older records which sometimes prevents this update.)

  int counter = 0;
  foreach (var dr in Db.OrderDtl.Where(x => x.Reference != x.Reference_c && x.Reference_c==string.Empty))
  {
    counter++;
    
    dr.Reference_c = dr.Reference;
    
    if (counter>1000)
      break;   
  }

Here is where the oddities are occurring…

This works perfectly fine if it is ran as part of a BPM.
However, if you schedule this function to run, it will not update the table.
Does anyone know why or have a fix so this can be ran as a scheduled function?

Thanks,
Karen

Try adding a transaction to the function. (I assuming the function is set to read / write db)?

I’ve tried several iterations of this:

  • Flagging the Requires Transaction
  • Internal Use Only
  • Transaction scope in code
using(var txScope = Ice.IceContext.CreateDefaultTransactionScope())
{
  int counter = 0;
  foreach (var dr in Db.OrderDtl.Where(x => x.Reference != x.Reference_c && x.Reference_c==string.Empty))
  {
    counter++;
    
    dr.Reference_c = dr.Reference;
    
    if (counter>1000)
      break;
   
  }
  

  txScope.Complete();
}  
  

The Db.Validate() is not here because there is no accessible extension method in the ILibraryContext.

I even had another thought since it will work as part of a BPM. I put the function execution on the Post Processing of Tip.GetNewTip. This works and updates the OrderDtl records as expected when you call the Tip.GetNewTip from the GUI. So I thought why not create a function that calls the Tip.GetNewTip and try to run it as a scheduled function. In this case, it doesn’t update the OrderDtl records as expected.

What is your Epicor version?

The version I’m doing this in is 10.2.700.8.

I also tried it in a 10.2.700.16 environment.

Karen,

I saw some post that you will need to have erpContext to call Db

Give this a try. Remember to add the reference

var context = Ice.Services.ContextFactory.CreateContext();
var erpContext = new Erp.Internal.Lib.CCredChk(context);

using(var txScope = Ice.IceContext.CreateDefaultTransactionScope())
{
int counter = 0;
foreach (var dr in erpContext.Db.OrderDtl.Where(x => x.Reference != x.Character01 && x.Character01==string.Empty))
{
counter++;

dr.Character01 = dr.Reference;

if (counter>1000)
  break;

}

erpContext.Db.Validate();
txScope.Complete();
}

image

3 Likes

Thank you! This is exactly what I was looking for. I had to make one other change due to types, but it works now when running as a scheduled function.

Here is the updated final code for anyone who may need it later:

var context = (Erp.ErpContext)Ice.Services.ContextFactory.CreateContext();
var erpContext = new Erp.Internal.Lib.CCredChk(context);


using(var txScope = Ice.IceContext.CreateDefaultTransactionScope())
{
  int counter = 0;
  foreach (var dr in erpContext.Db.OrderDtl.Where(x => x.Reference != x.Reference_c ))
  {    
    dr.Reference_c = dr.Reference;
    
    erpContext.Db.Validate(dr);
    break;
  }
  
  txScope.Complete();
}  
  
2 Likes