Create, Get, and Save Entity Activities
When a form sequence is created and saved, Sequence Designer automatically creates a workflow definition containing In/Out arguments for all entities that are referenced in the forms within the sequence. The arguments are used to pass data between Forms Builder and Workflow Composer. The argument names match the entity types. The parameters associated with the entities are not initialized by default. The entities associated with the arguments are not automatically created in the workflow. It is the responsibility of the user building the form to add the necessary CreateEntity<>, GetEntity<>, and SaveEntity<> activities in appropriate locations of the workflow definition. Appropriate locations are Transitions (e.g., Next, Submit, Back) and States (i.e., forms) in the StateMachine workflow.
CreateEntity<>
The CreateEntity<> activity is usually placed in the Entry Sequence of the first State (form) in a StateMachine workflow. Often, one or more Assign activities follow the CreateEntity<> activity.
GetEntity<>
The GetEntity<> activity can be used to retrieve data from the database. The activity could be placed on the Welcome form so that previously entered data prefills the form fields when the form is displayed.
The following table illustrates the behavior of Forms Builder and Workflow Composer depending on the user scenario. The StudentEntity and ContactEntity are used as examples in the table; however, the concept applies to other entities as well.
User scenario | Which workflow activity is needed in the first form? | Is the FormInstance.UserInfo property populated in Workflow Composer? | Is the Login field populated on the form? | Notes |
---|---|---|---|---|
Anthology Student | ||||
Anonymous user | CreateEntity — StudentEntity | — NA — | — NA — | |
New user creating an account | CreateEntity — StudentEntity | Yes | Yes | Add an Assign activity to assign studentEntity.FirstName = formInstance.UserInfo.FirstName The FormInstance.UserInfo comes from the login account information. The same assignment can be done for all other account fields in FormInstance.UserInfo to prepopulate those fields for StudentEntity in form. |
Existing user logged in | GetEntity — StudentEntity | Yes | Yes | |
CampusNexus CRM | ||||
Anonymous user | CreateEntity — ContactEntity | — NA — | — NA — | |
New user registering as a contact | GetEntity — ContactEntity | No (get data from the ContactEntity) | No by default (get data from the ContactEntity) | |
Existing user logged in | GetEntity — ContactEntity | No (get data from the ContactEntity) | No by default (get data from the ContactEntity) |
SaveEntity<>
The SaveEntity<> activity can be placed in the Trigger or Action area of the Next transition that leads to the End State. A SaveEntity<> activity must be paired with each CreateEntity<> or GetEntity<> activity to ensure that the data collected in the form sequence is persisted to the database.
See Workflow Help for more details on the CreateEntity<>, GetEntity<>, and SaveEntity<> activities.
Best Practice to Prevent DbUpdateConcurrency Exceptions
A DbUpdateConcurrency error occurs when an attempt is made to update an instance of an entity via a Save activity, but that instance has been modified by another user in the time from when the instance was initially retrieved in the workflow to the point in time when the Save activity executes.
The best practice to avoid this error is to add a TransactionScope activity to the workflow. Use the defaults of IsolationLevel = Serializable, and a timeout of 1 minute.
Within that TransactionScope, add a GetEntity activity to retrieve the instance of the entity prior to the execution of the SaveEntity activity. Any property values that need to be updated prior to saving can be done so via Assign statements right after the Get activity and right before the Save activity.
A transaction locks the database to give the workflow a chance to read and update with no other process simultaneously doing the same. Read about the other less aggressive isolation levels as they may be adequate for the purpose based on the type of updates being done and produce less overhead. Google “TransactionScope IsolationLevel Activities”. A “RepeatableRead” may be sufficient.
This pattern will eliminate any chance that another user will update this record in between the execution of the Get and Save activities within the workflow.