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).