The LLBLGen Pro runtime framework has full support for the designer's 'Action Combination' feature. In the LLBLGen Pro designer, a user can define which actions are allowed for a given entity - target database combination. Actions are what can be done with an entity: Create, Retrieve, Update and Delete. What is allowed is defined on the mapping of an entity to a given target. Below are the characteristics of this feature.
The following action combinations are definable on entities. They're
derived from the
CRUD group of actions (Create, Retrieve, Update and
R (retrieve) is always part of the set, because it's impossible
to avoid retrieve operations through projections. These action
combinations are only in use for operations on tables/views and
specifyable on entity mappings to table/view. Typed view, stored
procedure and TVF mappings are not using the actions, as they're always
Combinations marked with
* require the entity to have at least one
field marked as identifying field.
CRUD*. The default.
CRU*. Disallows deletes. Requires PK for update
CR. Disallows updates and deletes. Doesn't require a PK though retrieval of individual entities might be challenging considering no PK means no way to identify a unique row.
CRD*. Disallows updates. Requires PK for delete.
RU*. Disallows inserts and deletes. Requires PK for update.
RD*. Disallows inserts and updates. Requires PK for delete.
R. Disallows inserts, updates and deletes. Doesn't require PK, individual entity retrieval might be limited if no pk is present.
RUD*. Disallows inserts. Requires PK for update and delete.
An entity requires a PK if at least one mapping of the entity has an action combination defined which requires a PK being present.
When one of the four actions is about to take place in the runtime, the entity involved is checked with the persistence info. As Retrieve is always part of any action, the actions to check are Update, Insert and Delete. This isn't done with implementing using the Authorizer methods, as that would allow the user to override the settings easily. This means that an Authorizer which doesn't allow an action while the entity itself allows it can overrule the action defined for the entity, however if the authorizer allows it and the entity mapping itself doesn't, the action isn't allowed.
Delete / Update Directly and individual Delete methods will report false when an entity is Deleted / Updated directly which doesn't have the Delete / Update action as an allowed action. This is in line with the result of a denied delete/update through an Authorizer. The Save related methods report true when an entity doesn't have the required action in its action combinations. This is also in line with what an Authorizer will result in. So in short it's equal to when an Authorizer denies the action. This also means that saving a modified entity which doesn't have the insert/update action will still open a transaction/connection.
When an entity is passed to an update/save method, and the entity is dirty (changed) but the entity has no Update action defined in its action combination, the entity is ignored for the action. This is equal to an Authorizer denying the action.
As the actions are defined on the mapping it can be an entity is r/w on one database but r/o on another database, the entity itself can't be denying changes. This means a dirty entity can end up in a graph for persistence to a database onto which it has no update/create action defined. To throw exceptions in that case results in a lot of inconvenient code for the user, so the runtime will ignore the entity 'silently' as if it's not there.