Saving Multiple Root Objects

When you save an editable root object the data portal may save that object, and all its child objects, in a transaction (if you apply the Transactional attribute). Sometimes the need exists to save more than one root object as part of a single transaction (a single data portal Save() call).

To save multiple root objects in a single transaction (single data portal Save() call), you need to "wrap" the root objects into another root object.

Typically you'll use a CommandBase object to act as the wrapper. Assuming you have CustomerEdit and ProductEdit objects you want to save as a single operation, the command wrapper would look like this:

[Serializable]
public class CustomerProductSaver : CommandBase
{
  public CustomerEdit Customer { get; private set; }
  public ProductEdit Customer { get; private set; }

  public static CustomerProductSaver SaveObjects(
    CustomerEdit customer, ProductEdit product)
  {
    var cmd = new CustomerProductSaver
      { Customer = customer, Product = product };
    cmd = DataPortal.Execute(cmd);
    return cmd;
  }

  [Transactional(TransactionTypes.TransactionScope)]
  protected override void DataPortal_Execute()
  {
    using (var ctx = ConnectionManager.GetManager(...))
    {
      Customer = Customer.Save();
      Product = Product.Save();
    }
  }
}

The DataPortal_Execute() method uses the Transactional attribute to ask the data portal to ensure that the code runs in a transaction. It also opens the database connection so the connecion can be reused across both the CustomerEdit and ProductEdit objects (assuming they also use the ConnectionManager to get their connection).