I have a complex domain model built on top of a legacy system that I\'ve built most of the \"get\" methods for - typically just by passing around database primary key IDs. E
You can make your objects all expose the same method, call it AttemptSave, and calling this method on the parent object will result in it calling in cascade those methods of all children.
The method could return a boolean value indicating the success of the operation. No need to throw exceptions to make it easy for the UI developer.
Then expose a method GetValidationErrors. If AttemptSave returned false, then the UI developer should call this method to retrieve and display errors.
Alternatively, you can add a validation method Validate which will precheck the object hierarchy. You can return validation errors via GetValidationErrors. Then the call to AttemptSave will be performed. Should it fail, you can return the errors with GetOperationErrors.
Something in the philosophy of SQL. Either your query succeeded or not, you can always look at @@ROWCOUNT to get an idea whether the query did at least part of the job.