🚀 Welcome to MDriven Learn –  MDriven is now on Discord!  Don’t miss the latest Release Notes.
OCLOperators PSEvalValue
This page was created by Hans.karlsen on 2022-01-11. Last edited by Wikiadmin on 2026-07-29.

You can use PSEvalValue in an OCL expression or EAL (action language) expression to calculate and return one value from persistent storage without loading the matching objects into memory.

What PSEvalValue does

OCLps is the subset of OCL that MDriven translates to SQL for evaluation in the database. PSEvalValue lets an OCL or EAL expression evaluate an OCLps expression and use its scalar result, such as a count or sum.

Use PSEvalValue when you need a value derived from a potentially large database set. For example, you can count asynchronous tickets that have an error without loading every SysAsyncTicket object into memory.

PSEvalValue does not subscribe to changes in the database result. This is the key trade-off: the database query can avoid loading many objects, but a changed row does not automatically update the value in the user interface.

Expression template

SomeClass.PSEvalValue(<ps-expression>, <dependon>)
Part Meaning
SomeClass A class used to start the operator call.
<ps-expression> An OCLps expression that MDriven evaluates against persistent storage. It must produce the value you need.
<dependon> An expression whose change causes PSEvalValue to run again. Use this to define when the displayed value is refreshed.

Add a database-calculated value

  1. Identify the value you need. For example, count tickets where Error has a value.
  2. Write the query as OCLps. Keep it within the OCLps subset; OCLps has no side effects and cannot call your methods, including methods marked IsQuery.
  3. Wrap the OCLps expression in PSEvalValue.
  4. Choose a dependon expression that changes whenever you want the query to run again.
  5. Test both the returned value and its refresh behavior after database data changes.

Example: count tickets with errors

The following expression can be used in a method that has userName as a parameter:

SysAsyncTicket.PSEvalValue(
  SysAsyncTicket.allInstances->select(at|at.Error.notNull)->size,
  Calendar.Now
).asString

The OCLps expression selects SysAsyncTicket rows where Error is not null and returns their count. The final .asString converts that number to a string for a string result or display context.

In the BaseApp model, Calendar.Now updates every minute. Using it as dependon therefore causes the count to be evaluated again every minute while the value is in use. Without a changing dependency, creating, updating, or deleting a matching ticket does not itself cause this PSEvalValue result to refresh.

Choose the refresh dependency deliberately

PSEvalValue does not track the objects or rows used by its OCLps expression. Do not expect the normal MDriven subscription behavior for the query result.

Need Depend-on approach Example
Refresh at a regular interval Use a value that changes on that interval. Calendar.Now refreshes the ticket count every minute in BaseApp.
Refresh when an input to the query changes Use that input as the dependency. A count filtered by a selected date can depend on the selected date value.
Need automatic updates when matching objects change Consider querying the matching objects with PSEval instead, then use normal OCL on the loaded set. For an article's liked comments, PSEval can load only comments with a like, allowing normal object subscriptions for those loaded objects.

For a concrete comparison of counting likes in the database versus loading a filtered object set, see HowTos:OCLps Example.

Limits and performance

No result-set subscription

PSEvalValue does not fetch changes to the query result set automatically. A new row that starts matching the filter, or an existing row that stops matching it, does not update the value until dependon changes and the expression is reevaluated.

This can make PSEvalValue unsuitable where the displayed value must immediately reflect every change to the underlying objects. In that case, evaluate whether PSEval better fits the requirement.

OCLps is not all OCL

OCLps is a restricted subset of OCL designed for database evaluation. It has no side effects, cannot use model methods, and does not support tuple-returning operations such as collect and groupby. Read Documentation:OCLps before designing a complex persistent-storage expression.

Database query cost

Each reevaluation runs a database query. Add and verify the SQL Server indexes and other database performance settings needed for the filters, joins, ordering, and aggregations in your expression. A timer-based dependency can repeatedly execute the query, so use an interval and query shape appropriate for the data volume.

Always validate a new expression against known data. Confirm that the value is correct and that it performs acceptably with representative database volumes.

Select the right operator

Requirement Operator Result
Return one database-calculated value, such as a count PSEvalValue A scalar value
Return persistent objects for further normal OCL processing PSEval A set of objects
Return multiple values as tuples PSEvalTuples Tuples
Use a SQL expression or stored procedure instead of OCLps sqlpassthrough SQL result or tuples, depending on the expression

See also