BufferCopy.Clone vs BufferCopy.Copy

In the process of doing an upgrade from 2023.2.22 to 2025.2.14, and needing some detail around the difference of BufferCopy.Clone Vs BufferCopy.Copy in an Epicor Function.

After performing an upgrade conversion I have errors stating that ‘BufferCopy’ does not contain a definition for ‘Clone’ When I look at the intellisense I see

I don’t really understand why there is duplication there. That’s the first thing. The next thing I really wanted to ask for people who are much more skilled than myself, is there a difference and if so could you explain?

Thanks.

The intellisense is just not complete, those are different signatures for the same thing basically.

Oops when I was meaning differences I was meaning differences between BufferCopy.Clone and .Copy. Support person hate post right there… Two questions in one… Sorry.

I have this buried in my notes.

var dsReceipt = bo.GetByID(vendorNum, purPoint, packSlip);
 
// 
// Example how to Copy a few Tableset rows to New Tableset
//
var dsNew = new Erp.Tablesets.ReceiptTableset { 
    RcvHead = { 
        Epicor.Data.BufferCopy.Clone(dsReceipt.RcvHead[0]) 
    },
    RcvMisc = {
        Epicor.Data.BufferCopy.Clone(dsReceipt.RcvMisc.Where(x => x.MiscSeq == seqNum).FirstOrDefault()),
        Epicor.Data.BufferCopy.Clone(dsReceipt.RcvMisc.Where(x => x.MiscSeq == seqNum).FirstOrDefault())
        //new Erp.Tablesets.RcvMiscRow { EnableToBuildYourOwn }
    }
};
 
dsNew.RcvMisc[0].RowMod = "U";
 
 
// 
// Example how to Copy a LINQ Row to Tableset
//
 
// Erp.Tablesets.ReceiptTableset 
var dsNew3 = new Erp.Tablesets.ReceiptTableset {
    RcvHead = { 
        Epicor.Data.BufferCopy.Copy<Erp.Tables.RcvHead, Erp.Tablesets.RcvHeadRow>(Db.RcvHead.Where(s => s.Company == Session.CompanyID 
                    && s.PackSlip == packSlip 
                    && s.VendorNum == vendorNum 
                    && s.PurPoint == purPoint).FirstOrDefault())
    },
    // Erp.Tablesets.RcvMiscTable
    RcvMisc = {
        // Erp.Tablesets.RcvMiscRow
        Epicor.Data.BufferCopy.Copy<Erp.Tables.RcvMisc, Erp.Tablesets.RcvMiscRow>(Db.RcvMisc.Where(s => s.Company == Session.CompanyID 
                    && s.PackSlip == packSlip 
                    && s.VendorNum == vendorNum 
                    && s.PurPoint == purPoint
                    && s.MiscSeq == seqNum).FirstOrDefault()),
        // Erp.Tablesets.RcvMiscRow     
        Epicor.Data.BufferCopy.Copy<Erp.Tables.RcvMisc, Erp.Tablesets.RcvMiscRow>(Db.RcvMisc.Where(s => s.Company == Session.CompanyID 
                    && s.PackSlip == packSlip 
                    && s.VendorNum == vendorNum 
                    && s.PurPoint == purPoint
                    && s.MiscSeq == seqNum).FirstOrDefault())
    }
};
 
dsNew3.RcvMisc[0].RowMod = "U";
 
bo.OnChangeMiscDocActualAmt(vendorNum, purPoint, packSlip, seqNum, _value, ref dsNew);
bo.Update(ref dsNew);
 
 
// 
// Example how to Copy a LINQ Row to a LINQ Row (Erp.Tables.RcvMisc)
//
 
// Epicor Clone and Copy both will create a new GUID when the target is a LINQ Row
var LINQtoLINQExample = Epicor.Data.BufferCopy.Clone(Db.RcvMisc.Where(s => s.Company == Session.CompanyID 
    && s.PackSlip == packSlip 
    && s.VendorNum == vendorNum 
    && s.PurPoint == purPoint
    && s.MiscSeq == seqNum).FirstOrDefault());
 
// If you want to Preserve the GUID you must use Copy with 3rd param true
Erp.Tables.RcvMisc linqRowExample2 = new Erp.Tables.RcvMisc();
Epicor.Data.BufferCopy.Copy(xrow, linqRowExample2, true);

//
// Other Examples
//
// Example 1
UD03Row copyRow = new UD03Row();
BufferCopy.CopyExceptFor(ud03Row, copyRow, "SysRowID");

// Example 2
Ice.Tables.UD05 NewUD05 = null;
Db.UD05.Insert(NewUD05);
BufferCopy.CopyExceptFor(UD05, NewUD05, UD05.ColumnNames.SysRevID, UD05.ColumnNames.SysRowID);
NewUD05.Key3 = Convert.ToString(quoteRow.QuoteNum);
NewUD05.Key4 = Convert.ToString(quoteRow.QuoteLine);

Not sure why they removed Clone. I liked it.

We had to switch to something like

var newJcRow = new Erp.Tablesets.JobClosingRow();
Epicor.Data.BufferCopy.Copy(jcRow, newJcRow);
ds.JobClosing.Add(newJcRow);

Looks like Copy replaces Clone now.

This worked for me (2025.2.6):

CallService<UD100SvcContract>((svc) =>
  {
    var ds = svc.GetBySysRowID(Guid.Parse("2d766025-cdff-44de-b79e-1b53670b0458"));
    var dsRow = ds.UD100.First();
    
    var dsCopy = new UD100Tableset();
    var dsRowCopy = BufferCopy.Copy(dsRow);

    dsCopy.UD100.Add(dsRowCopy);
  });

There’s also this fun copy if you want to copy an entire tableset:

CallService<UD100SvcContract>((svc) =>
  {
    var ds = svc.GetBySysRowID(Guid.Parse("2d766025-cdff-44de-b79e-1b53670b0458"));
    var dsCopy = new UD100Tableset();

    DataCopy.CopyTableset(ds, dsCopy);
  });

Probably because it did something different than the .net DataSet.Clone() method. The standard method copies the DataSet object structure, but not the data itself.