You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Acumatica中从Graph1触发操作批量写入其他表的推荐实现方案

Great question! In Acumatica, sticking to the framework's built-in patterns is key to maintaining data integrity, enforcing business logic, and keeping your code maintainable. Here's the recommended approach for your scenario:

1. Use Graph Instances Instead of Direct PXDatabase Calls

Adding Data Views for Table2/Table3 to Graph1 isn't necessary, but leveraging their dedicated graphs (Graph2 and Graph3) is the best practice. This ensures all validation rules, event handlers (like RowInserted, FieldUpdated), and system field auto-population (e.g., CreatedByID, CreatedDateTime) are executed—something direct PXDatabase.Insert would bypass, risking inconsistent data.

Here's how to implement this:

  • Create instances of Graph2 and Graph3 using PXGraph.CreateInstance<T>() (since they're not dependencies of Graph1).
  • Add your batch records to each graph's primary Data View.
  • Call PressSave() on each graph to commit the changes.

2. Wrap All Operations in PXTransactionScope

To guarantee atomicity (either all inserts succeed or none do), wrap the entire workflow in a PXTransactionScope. This handles database transaction management and automatic rollback if any step fails.

Example Code Snippet

public PXAction<Table1> BatchInsertRecords;
[PXButton]
[PXUIField(DisplayName = "Batch Insert to Table2/3")]
protected void batchInsertRecords()
{
    using (var transactionScope = new PXTransactionScope())
    {
        var currentTable1Record = Base.Table1Records.Current;
        if (currentTable1Record == null) return;

        // Insert batch records into Table2 via Graph2
        var graph2 = PXGraph.CreateInstance<Graph2>();
        foreach (var table2Record in GenerateTable2Records(currentTable1Record))
        {
            graph2.Table2Records.Insert(table2Record);
        }
        graph2.PressSave();

        // Insert batch records into Table3 via Graph3
        var graph3 = PXGraph.CreateInstance<Graph3>();
        foreach (var table3Record in GenerateTable3Records(currentTable1Record))
        {
            graph3.Table3Records.Insert(table3Record);
        }
        graph3.PressSave();

        // Commit the entire transaction
        transactionScope.Complete();

        // Refresh Graph1 to reflect any related changes
        Base.Table1Records.View.RequestRefresh();
    }
}

// Helper method to generate Table2 records
private IEnumerable<Table2> GenerateTable2Records(Table1 sourceRecord)
{
    // Replace with your logic to create multiple Table2 records
    yield return new Table2
    {
        Table2Field1 = sourceRecord.Table1FieldA,
        Table2Field2 = DateTime.Now,
        // Populate all required fields here
    };
    yield return new Table2
    {
        Table2Field1 = sourceRecord.Table1FieldB,
        Table2Field2 = DateTime.Now,
    };
}

// Helper method to generate Table3 records
private IEnumerable<Table3> GenerateTable3Records(Table1 sourceRecord)
{
    // Similar logic for Table3 records
    yield return new Table3
    {
        Table3FieldX = sourceRecord.Table1FieldC,
        Table3FieldY = "Batch Inserted"
    };
}

When Might You Use PXDatabase.Insert?

Only consider direct PXDatabase.Insert if Table2 and Table3 have zero business logic, validation rules, or event handlers. Even then, using the graph approach is safer for future changes—if someone adds logic to those tables later, your code will automatically respect it without modification.

内容的提问来源于stack exchange,提问作者Joseph Caruana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:40:16