MongoDB
Update
6 samples, from the least code that works to complete workflows.
What an update does
| Rule | On MongoDB |
|---|---|
| What is written | Only the attributes present ($set); a field left out keeps its value; null is stored as null |
| Which documents | By the declared id (default), a declared key (ArxMatch.Key) or any fields (ArxMatch.Columns); match fields are never written |
| Nothing matched | ARX2002 RecordNotFound |
| RequireSingleRow | More than one match is ARX2003 and nothing changes |
| The id | Can't change: MongoDB's _id is immutable (ARX8001) |
| Match values | A document or array given as a match value is compared as data ($eq), never run as an operator |
| Concurrency | Optional. Declare a version column (.Version(table, column) in the schema catalog) and every update checks it in the same statement (a read returns the version with each record, so read, change and update carries it): an entity that carries an old version is ARX2004 RecordChanged and nothing is written, and each update adds one to the version. .Version(table, column, required: true) refuses an update that doesn't carry it (ARX1001). Without a version column the last writer wins. |
| Rows by a condition | Update finds rows by equal values: the id, a declared key, or columns you give values for (ArxMatch.Columns). To change every row that meets a condition (amount > 100), pass the values and an ArxFilterExpression to UpdateMultipleAsync(values, filter): one call, all or nothing, from 0.1.0-preview.5 (UpdateMultiple, Basics). Before that version: read the rows with RetrieveMultipleAsync and pass them to UpdateMultipleAsync. |
The samples
Basics
The least code that works.
1Update one recordProgressiveThe smallest update, in three scenarios: by the id Create returned, clearing a value, and a record that isn't there.
The three ways to find the documents to change, in four scenarios: by a declared key, by any fields (several documents), with RequireSingleRow, and many entities at once, all or nothing.
Real cases
What an application does: a small CRM and product catalogue.
1Catch an injection attemptProgressiveTwo attacks on an update endpoint: an operator as a field name, and a match value built to match every document.
Advanced cases
Dependency injection, transactions, batch scopes and setting the service up.
1Update in a batch scopeAdvancedCreates and updates in one batch scope, in two scenarios: committed when the body returns, and rolled back when the body throws.
A security check around updates (SecurityGuard, in the project root), in four scenarios: an API batch of changes passes through; an attack hidden in one item refuses the whole batch and is logged; a list of allowed fields stops unknown names before ARX; and a false positive from your own configuration is reported as a bug, not an attack, so nobody is blocked.
The service set up from the database instead of by hand, then updating through it, in two scenarios: preload the lead collection at startup, and updating with Strict on, where only the preloaded fields may be named.