-
Notifications
You must be signed in to change notification settings - Fork 4
Read only access
A db context, or a single repository, can be configured read-only: every write on the underlying collections is denied at the driver boundary, while reads keep working normally. Use it to consume collections owned by another application, with no possibility of writing to them by mistake.
Make a whole context read-only from its options:
builder.Services.AddScriniumWithHangfire()
.AddDbContext<IReadOnlySampleDbContext, ReadOnlySampleDbContext>(options =>
{
options.ConnectionString = connectionString; // the owner application's database
options.IsReadOnly = true;
});Or make a single repository read-only from its RepositoryOptions, keeping the rest of the
context writable:
public IRepository<Cat, string> Cats { get; } = new Repository<Cat, string>(
new RepositoryOptions<Cat>("cats") { IsReadOnly = true });IRepository.IsReadOnly reports the effective flag — true when required by the repository's own
options or by the context's — and repositories with different flags coexist on the same context.
Enforcement lives on the guarded collection wrapper, so it also covers driver-level operations
through AccessToCollectionAsync. A denied operation throws
UnauthorizedAccessException.
| Denied on a read-only collection | Keeps working |
|---|---|
| Creates, replaces, deletes, bulk updates and upserts | Finds, queries, cursors, counts |
Aggregates writing to a collection ($out/$merge as last stage) and map-reduce with a collection output |
Read aggregates, inline map-reduce |
Tracked saves (SaveChangesAsync) reaching the collection |
Loading and tracking models in memory |
| Index and search-index management: creations, drops, updates | Index listing |
| Starting migrations and seeding (see below) | Migration status and history reads |
The database lifecycle belongs to the owner application, so a read-only context stays out of it:
-
Seeding is skipped:
SeedIfNeededAsynclogs and returnsfalse, soSeedDbContexts()at startup keeps working with a mix of writable and read-only contexts. -
Migrations are denied:
TryStartMigrationAsyncreturnsnull, and the Admin dashboard renders the context with a Read-only badge, without migration controls or status polling. Its Model schemas, Document structures and Missing origin references sections still work — counting and scanning are reads — telling you when the owner application has documents left on a deprecated schema, or dangling references; only the references removal, a write, is denied. -
There are no locks: reading
Engine.DbContextLock, and asking for a resource lock (GetResourceLock, or theTryAcquireResourceLockAsyncandIsResourceLockedAsyncfacades), throwInvalidOperationException, since claiming a lock would write the lock collection of a database this context can only read. Nothing in Scrinium reaches for the db context lock on a read-only context — the works it coordinates are already denied; coordinate your own locking through a db context the application can write.
On a writable context, migrations skip the index steps of its read-only repositories: the indexes of a shared collection belong to the collection owner, and must not be dropped or rebuilt by a consumer.
The consumer declares its own context over the owner's database, read-only:
public interface IReadOnlySampleDbContext : IDbContext
{
IRepository<Cat, string> Cats { get; }
}
public class ReadOnlySampleDbContext : DbContext, IReadOnlySampleDbContext
{
public IRepository<Cat, string> Cats { get; } = new Repository<Cat, string>("cats");
protected override IEnumerable<IModelMapsCollector> ModelMapsCollectors =>
[new ModelBaseMap(), new CatMap()];
}When the consumer also owns collections of its own on the same database, use a single writable
context and mark only the shared repositories read-only through their RepositoryOptions.
Note. The flag protects the ODM surface, not intentional bypasses:
Engine.Databasestill hands out the raw driver database, like it does under exclusive access.
Next: Exclusive access for the other access limitation, or Repositories for the rest of
RepositoryOptions.
Scrinium — source · issues (SCR) · GNU LGPL-3.0 · info@etherna.io
Getting started
Core concepts
Working with data
Serialization & mapping
Operations & maintenance
Advanced & reference