OrionLock.EntityFrameworkCore
3.0.0
dotnet add package OrionLock.EntityFrameworkCore --version 3.0.0
NuGet\Install-Package OrionLock.EntityFrameworkCore -Version 3.0.0
<PackageReference Include="OrionLock.EntityFrameworkCore" Version="3.0.0" />
<PackageVersion Include="OrionLock.EntityFrameworkCore" Version="3.0.0" />
<PackageReference Include="OrionLock.EntityFrameworkCore" />
paket add OrionLock.EntityFrameworkCore --version 3.0.0
#r "nuget: OrionLock.EntityFrameworkCore, 3.0.0"
#:package OrionLock.EntityFrameworkCore@3.0.0
#addin nuget:?package=OrionLock.EntityFrameworkCore&version=3.0.0
#tool nuget:?package=OrionLock.EntityFrameworkCore&version=3.0.0
OrionLock.EntityFrameworkCore
EF Core lock-table backend for OrionLock. One row per lock key in OrionLock_Locks; provider-agnostic (PostgreSQL, SQL Server, MySQL, SQLite).
modelBuilder.ApplyConfiguration(new OrionLockRowEntityTypeConfiguration());
services.AddOrionLock().UseEntityFrameworkCore<AppDbContext>();
Run dotnet ef migrations add Add_OrionLock_Locks.
Which clock decides expiry
A lease deadline is written by one host and read by another, so it is only meaningful if both compare it
against the same clock. This provider reads the instant from the database server on every acquire,
renew and release and does all lease arithmetic from that value — never from DateTime.UtcNow on the
application host. Clock drift between your application hosts therefore cannot cause two of them to hold
the same key; only the database's own clock matters. Verified on PostgreSQL (clock_timestamp()),
SQL Server (SYSUTCDATETIME()) and SQLite (CURRENT_TIMESTAMP).
Note that SQLite's CURRENT_TIMESTAMP has whole-second resolution, so leases shorter than about two
seconds are not meaningful there. Use a real server for sub-second leases.
Fencing tokens
OrionLock_Locks carries a FencingToken column, bumped by the same UPDATE that takes the row, and
handle.FencingToken returns it. Because the row is never deleted — release nulls the owner and leaves the
row — the counter only ever moves forward, which is what makes it usable as a fencing token.
The column is new: run a migration. If you cannot yet, call .Ignore(x => x.FencingToken) on the
entity in your own OnModelCreating; the provider reads column names from the EF model, finds nothing
mapped, and emits exactly the SQL it emitted before fencing existed while reporting no token. Locking
behaviour is unchanged either way.
Identifiers
Table and column names are taken from your EF model and quoted with the active provider's own rules, so
renaming the table, adding a schema or remapping a column all keep working, and reserved words are safe
(Key is reserved in T-SQL and MySQL). Earlier versions spliced the names in unquoted, which only parsed
on SQLite.
Reader-writer (shared/exclusive) lock
A provider-portable distributed reader-writer lock: many Shared (read) holders coexist, OR one Exclusive (write) holder. Works on any relational EF Core provider (SQL Server, PostgreSQL, ...) through provider-agnostic EF Core. Holds are clock-leased rows in OrionLock_RwHolds; per-resource serialization uses a Serializable transaction over an anchor row in OrionLock_RwResources, and the live DB clock (CURRENT_TIMESTAMP) is read per transition.
modelBuilder.ApplyConfiguration(new OrionLockRwHoldRowEntityTypeConfiguration());
modelBuilder.ApplyConfiguration(new OrionLockRwResourceRowEntityTypeConfiguration());
services.AddOrionLock().UseEntityFrameworkCoreSharedExclusive<AppDbContext>();
Create both tables via EF Core migrations / Database.EnsureCreated(), then resolve ISharedExclusiveLock.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Microsoft.EntityFrameworkCore.Relational (>= 9.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.0)
- OrionLock (>= 3.0.0)
-
net8.0
- Microsoft.EntityFrameworkCore.Relational (>= 9.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.0)
- OrionLock (>= 3.0.0)
-
net9.0
- Microsoft.EntityFrameworkCore.Relational (>= 9.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.0)
- OrionLock (>= 3.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 3.0.0 | 41 | 9/20/2026 |
| 2.0.0 | 127 | 7/29/2026 |
| 1.0.1 | 111 | 7/27/2026 |
| 1.0.0 | 127 | 6/30/2026 |
| 0.6.0 | 122 | 6/27/2026 |
| 0.5.0 | 123 | 6/26/2026 |
| 0.4.1 | 128 | 6/20/2026 |
| 0.4.0 | 120 | 6/19/2026 |
| 0.3.32 | 129 | 6/17/2026 |
| 0.3.31 | 112 | 6/16/2026 |
| 0.3.30 | 129 | 6/16/2026 |
| 0.3.28 | 113 | 6/15/2026 |
| 0.3.27 | 115 | 6/15/2026 |
| 0.3.26 | 114 | 6/13/2026 |
| 0.3.25 | 108 | 6/13/2026 |
| 0.3.24 | 116 | 6/12/2026 |
| 0.3.23 | 111 | 6/12/2026 |
| 0.3.22 | 126 | 6/11/2026 |
| 0.3.21 | 115 | 6/11/2026 |
| 0.3.20 | 109 | 6/11/2026 |