Entity Framework Core storage¶
Persists the op log and snapshots in any database EF Core supports,
through your existing DbContext.
Install¶
Setup¶
builder.Services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("App")));
builder.Services
.AddOpStream()
.UseEfCoreStorage<AppDbContext>();
The package adds two entities to your context — OpStreamStoredOp and
OpStreamSnapshot — via IModelConfiguration. Run dotnet ef migrations
add ... to generate the tables.
Provider compatibility¶
UseEfCoreStorage<TContext> is provider-agnostic — it works with
any EF Core provider you've already configured on your context:
- SQL Server
- PostgreSQL (Npgsql)
- MySQL (Pomelo)
- SQLite
- Oracle
- Cosmos DB
- …
If you already use EF Core, this is almost always the easiest path. For
fresh deployments without an existing context, the dedicated provider
packages (SQL Server, PostgreSQL, …)
add the schema directly without needing your own DbContext.
Schema¶
The migration adds two tables (default names; customizable via
OnModelCreating overrides on your context):
CREATE TABLE OpStreamStoredOps (
DocumentId NVARCHAR(255) NOT NULL,
Revision BIGINT NOT NULL,
AuthorId NVARCHAR(255) NOT NULL,
Timestamp DATETIMEOFFSET NOT NULL,
Payload VARBINARY(MAX) NOT NULL,
EngineType NVARCHAR(255) NOT NULL,
PRIMARY KEY (DocumentId, Revision)
);
CREATE TABLE OpStreamSnapshots (
DocumentId NVARCHAR(255) PRIMARY KEY,
Revision BIGINT NOT NULL,
Timestamp DATETIMEOFFSET NOT NULL,
State VARBINARY(MAX) NOT NULL
);
Performance notes¶
- The op-log primary key
(DocumentId, Revision)is also its cluster-aligned access pattern: every read is a forward scan from a base revision. - Snapshots compact the load path — see Snapshots.
- For very high write throughput documents, consider Redis storage and use EF Core only for long-term archive.
When to pick this¶
- You already have a
DbContextand want one migration story. - You're targeting an EF-Core-supported database that doesn't have a dedicated OpStream provider.
- You need sub-millisecond write latency — use Redis.