Table of Contents

Class ConcurrencyExtensions

Namespace
LinqToDB.Concurrency
Assembly
linq2db.dll
public static class ConcurrencyExtensions
Inheritance
object
ConcurrencyExtensions

Methods

DeleteOptimisticAsync<T>(IDataContext, T, CancellationToken)

Performs record delete using optimistic lock strategy asynchronously. Entity should have column annotated with OptimisticLockPropertyBaseAttribute, otherwise regular delete operation will be performed.

public static Task<int> DeleteOptimisticAsync<T>(this IDataContext dc, T obj, CancellationToken cancellationToken = default) where T : class

Parameters

dc IDataContext

Database context.

obj T

Entity instance to delete.

cancellationToken CancellationToken

Asynchronous operation cancellation token.

Returns

Task<int>

Number of deleted records. On providers that do not report affected rows the count is unreliable - always 0 on ClickHouse - so it cannot be used to detect an optimistic-concurrency failure there.

Type Parameters

T

Entity type.

DeleteOptimisticAsync<T>(IQueryable<T>, T, CancellationToken)

Performs record delete using optimistic lock strategy asynchronously. Entity should have column annotated with OptimisticLockPropertyBaseAttribute, otherwise regular delete operation will be performed.

public static Task<int> DeleteOptimisticAsync<T>(this IQueryable<T> source, T obj, CancellationToken cancellationToken = default) where T : class

Parameters

source IQueryable<T>

Table source with optional filtering applied.

obj T

Entity instance to delete.

cancellationToken CancellationToken

Asynchronous operation cancellation token.

Returns

Task<int>

Number of deleted records. On providers that do not report affected rows the count is unreliable - always 0 on ClickHouse - so it cannot be used to detect an optimistic-concurrency failure there.

Type Parameters

T

Entity type.

DeleteOptimistic<T>(IDataContext, T)

Performs record delete using optimistic lock strategy. Entity should have column annotated with OptimisticLockPropertyBaseAttribute, otherwise regular delete operation will be performed.

public static int DeleteOptimistic<T>(this IDataContext dc, T obj) where T : class

Parameters

dc IDataContext

Database context.

obj T

Entity instance to delete.

Returns

int

Number of deleted records. On providers that do not report affected rows the count is unreliable - always 0 on ClickHouse - so it cannot be used to detect an optimistic-concurrency failure there.

Type Parameters

T

Entity type.

DeleteOptimistic<T>(IQueryable<T>, T)

Performs record delete using optimistic lock strategy. Entity should have column annotated with OptimisticLockPropertyBaseAttribute, otherwise regular delete operation will be performed.

public static int DeleteOptimistic<T>(this IQueryable<T> source, T obj) where T : class

Parameters

source IQueryable<T>

Table source with optional filtering applied.

obj T

Entity instance to delete.

Returns

int

Number of deleted records. On providers that do not report affected rows the count is unreliable - always 0 on ClickHouse - so it cannot be used to detect an optimistic-concurrency failure there.

Type Parameters

T

Entity type.

UpdateOptimisticAsync<T>(IDataContext, T, CancellationToken)

Performs record update using optimistic lock strategy asynchronously. Entity should have column annotated with OptimisticLockPropertyBaseAttribute, otherwise regular update operation will be performed.

public static Task<int> UpdateOptimisticAsync<T>(this IDataContext dc, T obj, CancellationToken cancellationToken = default) where T : class

Parameters

dc IDataContext

Database context.

obj T

Entity instance to update.

cancellationToken CancellationToken

Asynchronous operation cancellation token.

Returns

Task<int>

Number of updated records. On providers that do not report affected rows the count is unreliable - always 0 on ClickHouse - so it cannot be used to detect an optimistic-concurrency failure there.

Type Parameters

T

Entity type.

UpdateOptimisticAsync<T>(IQueryable<T>, T, CancellationToken)

Performs record update using optimistic lock strategy asynchronously. Entity should have column annotated with OptimisticLockPropertyBaseAttribute, otherwise regular update operation will be performed.

public static Task<int> UpdateOptimisticAsync<T>(this IQueryable<T> source, T obj, CancellationToken cancellationToken = default) where T : class

Parameters

source IQueryable<T>

Table source with optional filtering applied.

obj T

Entity instance to update.

cancellationToken CancellationToken

Asynchronous operation cancellation token.

Returns

Task<int>

Number of updated records. On providers that do not report affected rows the count is unreliable - always 0 on ClickHouse - so it cannot be used to detect an optimistic-concurrency failure there.

Type Parameters

T

Entity type.

UpdateOptimisticWithRefreshAsync<T>(IDataContext, T, CancellationToken)

Performs record update using optimistic lock strategy asynchronously and refreshes the optimistic-lock column(s) on obj with the regenerated value(s) read back from the same statement (via OUTPUT / RETURNING). On providers without OUTPUT / RETURNING support the value is read back with a follow-up SELECT instead.

That follow-up SELECT is a separate statement, so the refreshed value is only guaranteed to be the one this update wrote when the call runs inside a transaction; without one a concurrent writer's value can be observed instead, and when the read-back matches no row at all - the row was deleted concurrently, or an entity query filter no longer accepts the updated values - the entity is left unrefreshed even though a non-zero count is returned. On SQL Server the OUTPUT path cannot be used against a table carrying any enabled UPDATE trigger - not just a version-generating one - because OUTPUT without INTO is rejected there; that also rules out the database-trigger variant of Auto.

public static Task<int> UpdateOptimisticWithRefreshAsync<T>(this IDataContext dc, T obj, CancellationToken cancellationToken = default) where T : class

Parameters

dc IDataContext

Database context.

obj T

Entity instance to update. Receives the regenerated optimistic-lock value(s) on success.

cancellationToken CancellationToken

Asynchronous operation cancellation token.

Returns

Task<int>

Number of updated records. When the entity declares at least one optimistic-lock column, 0 indicates an optimistic-concurrency failure and the entity is left untouched; the count is reliable wherever this method is supported, including on providers that do not report affected rows but do support OUTPUT / RETURNING (e.g. YDB). When the entity declares no optimistic-lock column the call degrades to a plain update: the OUTPUT / RETURNING path is not used, so the raw provider count is returned and is unreliable on every provider that does not report affected rows - including YDB, and always 0 on ClickHouse.

Type Parameters

T

Entity type.

Exceptions

LinqToDBException

Thrown when the provider supports neither single-statement UPDATE OUTPUT / RETURNING nor a reliable affected-rows count (e.g. ClickHouse), so the optimistic-concurrency result cannot be guaranteed. Also thrown when an optimistic-lock member has no setter, so the regenerated value cannot be written back onto obj. Also thrown on the read-back path when an operator in the source query does not expose the updated table as its own source (SelectMany / Join with a different outer, OfType / Cast over a base type), because the caller's filters then cannot be excluded from the read-back.

UpdateOptimisticWithRefreshAsync<T>(IQueryable<T>, T, CancellationToken)

Performs record update using optimistic lock strategy asynchronously and refreshes the optimistic-lock column(s) on obj with the regenerated value(s) read back from the same statement (via OUTPUT / RETURNING). On providers without OUTPUT / RETURNING support the value is read back with a follow-up SELECT instead.

That follow-up SELECT is a separate statement, so the refreshed value is only guaranteed to be the one this update wrote when the call runs inside a transaction; without one a concurrent writer's value can be observed instead, and when the read-back matches no row at all - the row was deleted concurrently, or an entity query filter no longer accepts the updated values - the entity is left unrefreshed even though a non-zero count is returned. On SQL Server the OUTPUT path cannot be used against a table carrying any enabled UPDATE trigger - not just a version-generating one - because OUTPUT without INTO is rejected there; that also rules out the database-trigger variant of Auto.

public static Task<int> UpdateOptimisticWithRefreshAsync<T>(this IQueryable<T> source, T obj, CancellationToken cancellationToken = default) where T : class

Parameters

source IQueryable<T>

Table source with optional filtering applied.

obj T

Entity instance to update. Receives the regenerated optimistic-lock value(s) on success.

cancellationToken CancellationToken

Asynchronous operation cancellation token.

Returns

Task<int>

Number of updated records. When the entity declares at least one optimistic-lock column, 0 indicates an optimistic-concurrency failure and the entity is left untouched; the count is reliable wherever this method is supported, including on providers that do not report affected rows but do support OUTPUT / RETURNING (e.g. YDB). When the entity declares no optimistic-lock column the call degrades to a plain update: the OUTPUT / RETURNING path is not used, so the raw provider count is returned and is unreliable on every provider that does not report affected rows - including YDB, and always 0 on ClickHouse.

Type Parameters

T

Entity type.

Exceptions

LinqToDBException

Thrown when the provider supports neither single-statement UPDATE OUTPUT / RETURNING nor a reliable affected-rows count (e.g. ClickHouse), so the optimistic-concurrency result cannot be guaranteed. Also thrown when an optimistic-lock member has no setter, so the regenerated value cannot be written back onto obj. Also thrown on the read-back path when an operator in the source query does not expose the updated table as its own source (SelectMany / Join with a different outer, OfType / Cast over a base type), because the caller's filters then cannot be excluded from the read-back.

UpdateOptimisticWithRefresh<T>(IDataContext, T)

Performs record update using optimistic lock strategy and refreshes the optimistic-lock column(s) on obj with the regenerated value(s) read back from the same statement (via OUTPUT / RETURNING). On providers without OUTPUT / RETURNING support the value is read back with a follow-up SELECT instead.

That follow-up SELECT is a separate statement, so the refreshed value is only guaranteed to be the one this update wrote when the call runs inside a transaction; without one a concurrent writer's value can be observed instead, and when the read-back matches no row at all - the row was deleted concurrently, or an entity query filter no longer accepts the updated values - the entity is left unrefreshed even though a non-zero count is returned. On SQL Server the OUTPUT path cannot be used against a table carrying any enabled UPDATE trigger - not just a version-generating one - because OUTPUT without INTO is rejected there; that also rules out the database-trigger variant of Auto.

public static int UpdateOptimisticWithRefresh<T>(this IDataContext dc, T obj) where T : class

Parameters

dc IDataContext

Database context.

obj T

Entity instance to update. Receives the regenerated optimistic-lock value(s) on success.

Returns

int

Number of updated records. When the entity declares at least one optimistic-lock column, 0 indicates an optimistic-concurrency failure and the entity is left untouched; the count is reliable wherever this method is supported, including on providers that do not report affected rows but do support OUTPUT / RETURNING (e.g. YDB). When the entity declares no optimistic-lock column the call degrades to a plain update: the OUTPUT / RETURNING path is not used, so the raw provider count is returned and is unreliable on every provider that does not report affected rows - including YDB, and always 0 on ClickHouse.

Type Parameters

T

Entity type.

Exceptions

LinqToDBException

Thrown when the provider supports neither single-statement UPDATE OUTPUT / RETURNING nor a reliable affected-rows count (e.g. ClickHouse), so the optimistic-concurrency result cannot be guaranteed. Also thrown when an optimistic-lock member has no setter, so the regenerated value cannot be written back onto obj. Also thrown on the read-back path when an operator in the source query does not expose the updated table as its own source (SelectMany / Join with a different outer, OfType / Cast over a base type), because the caller's filters then cannot be excluded from the read-back.

UpdateOptimisticWithRefresh<T>(IQueryable<T>, T)

Performs record update using optimistic lock strategy and refreshes the optimistic-lock column(s) on obj with the regenerated value(s) read back from the same statement (via OUTPUT / RETURNING). On providers without OUTPUT / RETURNING support the value is read back with a follow-up SELECT instead.

That follow-up SELECT is a separate statement, so the refreshed value is only guaranteed to be the one this update wrote when the call runs inside a transaction; without one a concurrent writer's value can be observed instead, and when the read-back matches no row at all - the row was deleted concurrently, or an entity query filter no longer accepts the updated values - the entity is left unrefreshed even though a non-zero count is returned. On SQL Server the OUTPUT path cannot be used against a table carrying any enabled UPDATE trigger - not just a version-generating one - because OUTPUT without INTO is rejected there; that also rules out the database-trigger variant of Auto.

public static int UpdateOptimisticWithRefresh<T>(this IQueryable<T> source, T obj) where T : class

Parameters

source IQueryable<T>

Table source with optional filtering applied.

obj T

Entity instance to update. Receives the regenerated optimistic-lock value(s) on success.

Returns

int

Number of updated records. When the entity declares at least one optimistic-lock column, 0 indicates an optimistic-concurrency failure and the entity is left untouched; the count is reliable wherever this method is supported, including on providers that do not report affected rows but do support OUTPUT / RETURNING (e.g. YDB). When the entity declares no optimistic-lock column the call degrades to a plain update: the OUTPUT / RETURNING path is not used, so the raw provider count is returned and is unreliable on every provider that does not report affected rows - including YDB, and always 0 on ClickHouse.

Type Parameters

T

Entity type.

Exceptions

LinqToDBException

Thrown when the provider supports neither single-statement UPDATE OUTPUT / RETURNING nor a reliable affected-rows count (e.g. ClickHouse), so the optimistic-concurrency result cannot be guaranteed. Also thrown when an optimistic-lock member has no setter, so the regenerated value cannot be written back onto obj. Also thrown on the read-back path when an operator in the source query does not expose the updated table as its own source (SelectMany / Join with a different outer, OfType / Cast over a base type), because the caller's filters then cannot be excluded from the read-back.

UpdateOptimistic<T>(IDataContext, T)

Performs record update using optimistic lock strategy. Entity should have column annotated with OptimisticLockPropertyBaseAttribute, otherwise regular update operation will be performed.

public static int UpdateOptimistic<T>(this IDataContext dc, T obj) where T : class

Parameters

dc IDataContext

Database context.

obj T

Entity instance to update.

Returns

int

Number of updated records. On providers that do not report affected rows the count is unreliable - always 0 on ClickHouse - so it cannot be used to detect an optimistic-concurrency failure there.

Type Parameters

T

Entity type.

UpdateOptimistic<T>(IQueryable<T>, T)

Performs record update using optimistic lock strategy. Entity should have column annotated with OptimisticLockPropertyBaseAttribute, otherwise regular update operation will be performed.

public static int UpdateOptimistic<T>(this IQueryable<T> source, T obj) where T : class

Parameters

source IQueryable<T>

Table source with optional filtering applied.

obj T

Entity instance to update.

Returns

int

Number of updated records. On providers that do not report affected rows the count is unreliable - always 0 on ClickHouse - so it cannot be used to detect an optimistic-concurrency failure there.

Type Parameters

T

Entity type.

WhereKeyOptimistic<T>(IQueryable<T>, T)

Applies primary key and optimistic lock filters to query for specific record. Entity should have column annotated with OptimisticLockPropertyBaseAttribute, otherwise only primary key filter will be applied to query.

public static IQueryable<T> WhereKeyOptimistic<T>(this IQueryable<T> source, T obj) where T : class

Parameters

source IQueryable<T>

Entity query.

obj T

Entity instance to take current lock field value from.

Returns

IQueryable<T>

Query with filter over lock field.

Type Parameters

T

Entity type.