Save business object¶
This operation is the core persistence pipeline for a single business object, whether it is a root object saved directly or a child object saved on behalf of a parent. It validates the object's entry state, re-runs rule evaluation, picks the correct delete, insert, or update branch purely from the object's own state flags (IsDeleted, IsNew, IsDirty), and then drives the matching before/after hook sequence on the data-access layer.
| Field | Value |
|---|---|
| Operation ID | OP-CORE-005 |
| Trigger | Caller invokes Save() on a root object or parent logic invokes SaveChild() on a child object. |
| Inputs | Business object state flags, current broken-rule state, CriteriaObject, and DataPortalInfo. |
| Outputs | Successful delete/insert/update/no-op result, False when errors remain after persistence, or thrown exception for invalid entry states. |
| Primary components | clsBusinessBase.Save, clsBusinessBase.SaveChild, clsBusinessBase.ExecuteData, clsDataAccess.DeleteObject, clsDataAccess.InsertObject, clsDataAccess.UpdateObject |
| Entry point | SAIF.Framework.Core\V1\BaseItems\clsBusinessBase.vb |
Steps¶
- Enter through
Save()for a root object orSaveChild()for a child object. - Root save rejects child objects; child save rejects non-child objects.
- Both entry points reject read-only objects and open edit levels before persistence starts.
- Re-evaluate validity before saving (BR-001, BR-002).
- If
IsValid = False, the method throwsApplicationExceptionthat includes the currentIDataErrorInfo.Errortext (BR-001, BR-002). - Clear current errors and warnings before data work begins.
Rules.BrokenRules.ClearErrorsAndWarnings()resets the transient error/warning surface so the next persistence attempt starts clean (BR-002).- Branch inside
ExecuteData()based on object state. - If
IsDeleted = TrueandIsNew = True, the method returnsTrueimmediately because nothing exists to remove. - If
IsDeleted = TrueandIsNew = False, the method delegates toDeleteObject(Me). - If
IsNew = TrueandIsDirty = True, the method delegates toInsertObject(Me). - If
IsDirty = TrueandIsNew = False, the method delegates toUpdateObject(Me). - If the object is not dirty, the method returns
Truewithout any data-access work. - Run the delete, insert, or update hook sequence inside
clsDataAccess. OnSave()runs first.- The data-access layer resolves the portal from
CriteriaObject.DataPortalInfo.PortalID, creates a new portal request, and calls the matchingBeforeDelete,BeforeInsert, orBeforeUpdatehook. - If one or more requests were queued, the portal connects, processes the batch, runs the matching
After*hook, and closes any reader results. - The portal disconnects in
Finally, andOnSaveComplete()runs after the persistence method finishes. - Translate post-persistence errors into the boolean result (BR-002).
- After each delete/insert/update branch,
ExecuteData()returnsFalsewhenErrorCount > 0. - Otherwise it returns
True.
Process flow¶
The following diagram visualizes this operation's control flow.
flowchart TD
Start([Save or SaveChild]) --> Valid{Valid save state?}
Valid -->|No| EndErr([Throw ApplicationException])
Valid -->|Yes| Deleted{Deleted?}
Deleted -->|Yes and new| EndNoop([Return true])
Deleted -->|Yes and existing| Delete[DeleteObject]
Deleted -->|No| NewDirty{New and dirty?}
NewDirty -->|Yes| Insert[InsertObject]
NewDirty -->|No| Dirty{Dirty?}
Dirty -->|Yes| Update[UpdateObject]
Dirty -->|No| EndNoop
Delete --> Finish[Return false if errors remain]
Insert --> Finish
Update --> Finish
Finish --> EndOk([Return save result])
Failure and edge-case behavior¶
- A root object cannot call
SaveChild()and a child object cannot callSave()— each entry point enforces the opposite role and throwsApplicationExceptionimmediately. - An invalid object fails before any data-access work starts, and the thrown exception carries the current
IDataErrorInfo.Errortext so the caller sees exactly which rule blocked the save. - A deleted object that was never persisted (
IsDeleted = TrueandIsNew = True) is treated as a successful no-op, since there is nothing in the data store to remove. - Data-access failures from the delete, insert, or update helpers are wrapped in
ApplicationException.
Related documentation¶
Sources¶
- SAIF.Framework.Core\V1\BaseItems\clsBusinessBase.vb
- SAIF.Framework.Core\V1\DataAccessLayer\clsDataAccess.vb