Shardis.Query.EntityFrameworkCore
0.1.0-prerelease0094
See the version list below for details.
dotnet add package Shardis.Query.EntityFrameworkCore --version 0.1.0-prerelease0094
NuGet\Install-Package Shardis.Query.EntityFrameworkCore -Version 0.1.0-prerelease0094
<PackageReference Include="Shardis.Query.EntityFrameworkCore" Version="0.1.0-prerelease0094" />
<PackageVersion Include="Shardis.Query.EntityFrameworkCore" Version="0.1.0-prerelease0094" />
<PackageReference Include="Shardis.Query.EntityFrameworkCore" />
paket add Shardis.Query.EntityFrameworkCore --version 0.1.0-prerelease0094
#r "nuget: Shardis.Query.EntityFrameworkCore, 0.1.0-prerelease0094"
#:package Shardis.Query.EntityFrameworkCore@0.1.0-prerelease0094
#addin nuget:?package=Shardis.Query.EntityFrameworkCore&version=0.1.0-prerelease0094&prerelease
#tool nuget:?package=Shardis.Query.EntityFrameworkCore&version=0.1.0-prerelease0094&prerelease
Shardis.Query.EntityFrameworkCore
Entity Framework Core query executor for Shardis (Where/Select pushdown, unordered streaming, preview ordered buffering, optional failure strategy decoration).
Install
dotnet add package Shardis.Query.EntityFrameworkCore --version 0.1.*
When to use
- Your shard-local persistence is EF Core and you want query pushdown and streaming.
- You need a tested executor that integrates with
DbContextper shard.
What’s included
EntityFrameworkCoreShardQueryExecutor— concrete executor translating queries into EF Core operations.EfCoreShardQueryExecutor.CreateUnorderedandCreateOrdered(buffered ordered variant; materializes then orders).EfCoreExecutionOptions(channel capacity, per-shard command timeout, shard concurrency, context lifetime control).EntityFrameworkCoreShardFactory<TContext>/PooledEntityFrameworkCoreShardFactory<TContext>for per-shard context creation.- Wiring examples for registering
DbContextinstances per shard.
Quick start
// Build a shard factory (pure creation only)
var dbFactory = new EntityFrameworkCoreShardFactory<MyDbContext>(sid =>
new DbContextOptionsBuilder<MyDbContext>()
.UseSqlite($"Data Source=shard-{sid.Value}.db")
.Options);
// (Optional) seed outside the factory
foreach (var sid in new[]{ new ShardId("0"), new ShardId("1") })
{
await using var ctx = await dbFactory.CreateAsync(sid);
// seed if empty
}
// Adapter to non-generic DbContext for executor
IShardFactory<DbContext> adapter = new DelegatingShardFactory<DbContext>((sid, ct) => new ValueTask<DbContext>(dbFactory.Create(sid)));
var exec = new EntityFrameworkCoreShardQueryExecutor(
shardCount: 2,
contextFactory: adapter,
merge: (streams, ct) => UnorderedMerge.Merge(streams, ct));
var query = ShardQuery.For<Person>(exec)
.Where(p => p.Age >= 30)
.Select(p => p.Name);
var names = await query.ToListAsync();
Integration notes
- Works with
Shardis.Querycore abstractions; register per-shardDbContextfactories in DI. - Recommended DI approach using
Shardis.DependencyInjection:
var services = new ServiceCollection()
.AddShards<MyDbContext>(2, shard => new MyDbContext(BuildOptionsFor(shard)))
.AddShardisEfCoreUnordered<MyDbContext>(
shardCount: 2,
contextFactory: new EntityFrameworkCoreShardFactory<MyDbContext>(BuildOptionsFor))
.DecorateShardQueryFailureStrategy(BestEffortFailureStrategy.Instance) // optional
.AddShardisQueryClient();
await using var provider = services.BuildServiceProvider();
var client = provider.GetRequiredService<IShardQueryClient>();
var active = await client.Query<Person>().Where(p => p.IsActive).CountAsync();
Samples & tests
- Samples: samples
Configuration / Options
- ChannelCapacity (
EfCoreExecutionOptions.ChannelCapacity): bounded backpressure for unordered merge (null = unbounded internal channel). - PerShardCommandTimeout: database command timeout per shard query (best‑effort; ignored if provider disallows).
- Concurrency: maximum shard fan‑out (limits simultaneous DbContext queries). Null = unbounded.
- DisposeContextPerQuery: if false, retains one
DbContextper shard for executor lifetime (reduces allocations; ensure thread-safety per context usage pattern). - Ordered factory:
AddShardisEfCoreOrdered/EfCoreShardQueryExecutor.CreateOrderedbuffers all shard results before ordering; use only for bounded result sets. - Failure strategy decoration: call
DecorateShardQueryFailureStrategy(BestEffortFailureStrategy.Instance)(or custom) after registering an executor.
Cancellation & Timeouts
All query methods accept a CancellationToken (propagated to EF Core async providers). If PerShardCommandTimeout is set, it is applied per shard query and restored for retained contexts.
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
var exec = EfCoreShardQueryExecutor.CreateUnordered(
shardCount,
contextFactory,
new EfCoreExecutionOptions { PerShardCommandTimeout = TimeSpan.FromSeconds(3) });
var names = await exec.Query<Person>().Select(p => p.Name).ToListAsync(cts.Token);
Backpressure
ChannelCapacity bounds the number of buffered items produced ahead of the consumer in unordered merges. Tune for throughput vs memory (typical range: 4–256). null = unbounded (fastest, more memory risk under very large fan-out).
Failure Behavior
Default: fail-fast — the first shard exception terminates the merged enumeration. To aggregate errors and continue best-effort across shards:
services.DecorateShardQueryFailureStrategy(BestEffortFailureStrategy.Instance);
Metrics & Tracing
The executor emits Activity instances via source name Shardis.Query with tags:
query.source,query.result,query.where.count,query.has.select,shard.count,query.duration.ms, and per-shardshard.index& optionaldb.command_timeout.seconds. Integrate with OpenTelemetry by adding anActivityListeneror OTEL SDK.
Capabilities & limits
- ✅ Pushes where/select operations to EF Core where supported.
- ⚠️ Ordered (buffered) factory materializes all results. Avoid for unbounded / very large sets.
- ⚠️ Ordered streaming improvements (k-way merge) planned; present variant trades memory for simplicity.
- 🧩 Requires EF Core provider matching your database version.
Versioning & compatibility
- SemVer; see CHANGELOG: CHANGELOG
Contributing
- PRs welcome. See CONTRIBUTING
License
- MIT — see LICENSE
Links
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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 (>= 10.0.1)
- Microsoft.EntityFrameworkCore.Relational (>= 10.0.1)
- Shardis.Query (>= 0.1.0-prerelease0094)
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 |
|---|---|---|
| 0.2.2 | 204 | 9/11/2025 |
| 0.2.2-prerelease0001 | 196 | 9/11/2025 |
| 0.2.1 | 194 | 9/10/2025 |
| 0.2.1-prerelease0001 | 194 | 9/9/2025 |
| 0.2.0 | 194 | 9/8/2025 |
| 0.1.0-prerelease0097 | 90 | 1/15/2026 |
| 0.1.0-prerelease0094 | 271 | 12/15/2025 |
| 0.1.0-prerelease0093 | 239 | 12/15/2025 |
| 0.1.0-prerelease0092 | 252 | 12/15/2025 |
| 0.1.0-prerelease0091 | 156 | 12/14/2025 |
| 0.1.0-prerelease0090 | 455 | 12/9/2025 |
| 0.1.0-prerelease0086 | 211 | 9/7/2025 |
| 0.1.0-prerelease0085 | 201 | 9/7/2025 |
Initial release. Full notes: https://github.com/veggerby/shardis/blob/main/CHANGELOG.md#010---2025-08-25