Table of Contents

Class EntityWriteExtensions

Namespace
DynaSharp
Assembly
DynaSharp.dll

The clauses of a write of an entity that its write rules ask for: IfVersion and IgnoreVersion for an entity with a VersionAttribute, and StoreKeyInputs for an update that may create the item. These are extension methods so that a write of a table without a schema, which has neither, does not offer them.

public static class EntityWriteExtensions
Inheritance
EntityWriteExtensions
Inherited Members

Examples

var cart = await carts.Get(Cart.Keys.Of("bob")).Consistent().ItemAsync(ct);
await carts.Update(Cart.Keys.Of("bob")).Set(Cart.Attrs.Lines, lines).IfVersion(cart!.Revision).SendAsync(ct);

Methods

IfVersion<T>(DeleteCommand<T>, long)

Deletes only if the item has this version. If the item has another version, sending throws ConditionalCheckFailedException.

public static DeleteCommand<T> IfVersion<T>(this DeleteCommand<T> command, long version) where T : IDynamoDbEntity<T>

Parameters

command DeleteCommand<T>

The command.

version long

The version last read.

Returns

DeleteCommand<T>

The command, which replaces this one.

Type Parameters

T

The entity. A table without a schema has no version, so it does not compile.

Remarks

Required for a versioned entity. A key does not carry a version, so a delete by a key of an entity with a VersionAttribute needs this or IgnoreVersion<T>(DeleteCommand<T>); a delete of an entity takes the version from it, and this checks another one in its place. RetryOnConflictAsync<TResult>(Func<CancellationToken, ValueTask<TResult>>, CancellationToken) repeats code that reads the version again.

Version 0 stands for an item that does not exist, so it renders attribute_not_exists on the partition key, and the delete fails on any item under the key. With Allow it looks at the version attribute instead, and deletes an item without one or with 0 in it.

Exceptions

ArgumentOutOfRangeException

version is negative, or MaxValue.

InvalidOperationException

T has no VersionAttribute.

IfVersion<T>(UpdateCommand<T>, long)

Updates only if the item has this version, and stores the next one, which Version returns. If the item has another version, sending throws ConditionalCheckFailedException.

public static UpdateCommand<T> IfVersion<T>(this UpdateCommand<T> command, long version) where T : IDynamoDbEntity<T>

Parameters

command UpdateCommand<T>

The command.

version long

The version last read.

Returns

UpdateCommand<T>

The command, which replaces this one.

Type Parameters

T

The entity. A table without a schema has no version, so it does not compile.

Remarks

Required for a versioned entity. A key does not carry a version, so an update of an entity with a VersionAttribute needs this or IgnoreVersion<T>(UpdateCommand<T>). Nothing is read or retried by itself: RetryOnConflictAsync<TResult>(Func<CancellationToken, ValueTask<TResult>>, CancellationToken) is how to ask for that, around code that reads the version again.

Version 0 stands for an item that does not exist, so it renders attribute_not_exists on the partition key and fails on any item under the key, also on one without a version attribute, which IgnoreVersion<T>(UpdateCommand<T>) writes to. With Allow it looks at the version attribute instead, and writes to an item without one or with 0 in it.

Exceptions

ArgumentOutOfRangeException

version is negative, or MaxValue, which has no next one.

InvalidOperationException

T has no VersionAttribute.

IgnoreVersion<T>(DeleteCommand<T>)

Lets the delete go out without the check.

public static DeleteCommand<T> IgnoreVersion<T>(this DeleteCommand<T> command) where T : IDynamoDbEntity<T>

Parameters

command DeleteCommand<T>

The command.

Returns

DeleteCommand<T>

The command, which replaces this one.

Type Parameters

T

The entity.

IgnoreVersion<T>(PutCommand<T>)

Writes the entity without the check of its version, for imports, migrations and an item written without a version, and still stores the next version, as a checked put does: Version is the version of the entity plus one. Conditions of your own stay, it holds wherever it stands in the chain, and on an entity without a VersionAttribute it changes nothing.

public static PutCommand<T> IgnoreVersion<T>(this PutCommand<T> command) where T : IDynamoDbEntity<T>

Parameters

command PutCommand<T>

The command.

Returns

PutCommand<T>

The command, which replaces this one.

Type Parameters

T

The entity. A table without a schema has no version, so it does not compile.

Remarks

The version still advances. Every write of a versioned entity stores a new version, also one without the check: an update adds 1 to the stored version, SET #v = if_not_exists(#v, :zero) + :one, so an item without one, or a new item, gets version 1, and a put or a batch stores the version of its entity plus one, as a checked put does. A writer that holds a copy read before this write then fails with ConditionalCheckFailedException, or in a transaction with TransactionCanceledException, instead of overwriting it. What this write itself overwrites is not checked: it wins over whatever another writer stored since, so it suits a change that does not depend on what was read, such as an Add to a counter.

Taking over an item without a version. Such an item reads as version 0, and a checked put at 0 fails with ConditionalCheckFailedException, because 0 says that no item has the key. orders.Put(order).IgnoreVersion() of the entity as it was read stores version 1, and the next write is an ordinary one. For a table that keeps such items, Allow is the better answer.

The last version. An entity at the last version its property holds throws OverflowException at Put(T), because it has no next one.

IgnoreVersion<T>(UpdateCommand<T>)

Lets the update go out without the check of the version, and still stores the next version, so that a copy read before it fails its next checked write. Version is null, because the update does not know the version it advanced from.

public static UpdateCommand<T> IgnoreVersion<T>(this UpdateCommand<T> command) where T : IDynamoDbEntity<T>

Parameters

command UpdateCommand<T>

The command.

Returns

UpdateCommand<T>

The command, which replaces this one.

Type Parameters

T

The entity.

Remarks

The version still advances. Every write of a versioned entity stores a new version, also one without the check: an update adds 1 to the stored version, SET #v = if_not_exists(#v, :zero) + :one, so an item without one, or a new item, gets version 1, and a put or a batch stores the version of its entity plus one, as a checked put does. A writer that holds a copy read before this write then fails with ConditionalCheckFailedException, or in a transaction with TransactionCanceledException, instead of overwriting it. What this write itself overwrites is not checked: it wins over whatever another writer stored since, so it suits a change that does not depend on what was read, such as an Add to a counter.

Setting the version yourself. An update that sets, adds to or removes the version attribute by its own action keeps that action, and the version is not advanced besides it. IfVersion(n) after this checks n and stores n + 1; before it, this throws.

Exceptions

InvalidOperationException

The update already has IfVersion, whose condition cannot be taken back.

StoreKeyInputs<T>(UpdateCommand<T>)

Stores the inputs of the key of the table as attributes of the item, as a Put does, for an update that may create the item: without it, an item an update created holds the key alone.

public static UpdateCommand<T> StoreKeyInputs<T>(this UpdateCommand<T> command) where T : IDynamoDbEntity<T>

Parameters

command UpdateCommand<T>

The command.

Returns

UpdateCommand<T>

The command, which replaces this one.

Type Parameters

T

The entity. A table without a schema has no key inputs, so it does not compile.

Remarks

What is written. SET #userId = if_not_exists(#userId, :v) per input, after the actions of the update and the keys of its indexes and before the discriminator. An item that exists keeps what it has, so this goes with IfExists(), IfNotExists() and a version alike. The value goes through the converter of the property and is the value, not the text of the key, and an action of the update on the attribute by a path given as a string takes precedence.

Why. A read of the entity restores the inputs from the key, but Select of such an input and a filter on it find nothing in an item that holds the key alone. A plain key and a key made of one property over its own attribute are their attribute, and a KeyOnlyAttribute has none, so an entity with nothing else changes nothing here.

A key given as strings. A template that cuts a value off, such as a timestamp in {At:yyyy-MM-dd}, gives it back only from a key the generator built, so a key given as strings throws for it when the update ends.