Explicit EF Core execution across multiple
DbContextand database boundaries.
EF Core owns data access. DataArc controls execution.
EF Core handles one DbContext well.
The difficulty starts when an application must coordinate work across:
- multiple
DbContextimplementations; - bounded contexts or modular persistence boundaries;
- separate databases;
- high-volume imports and synchronisation jobs;
- ordered, parallel, or transaction-aware workflows;
- database and script generation;
- structured execution outcomes.
Without a consistent execution model, this logic often spreads across repositories, handlers, services, factories, and orchestration code.
Application workflow
├── DbContext A
├── DbContext B
├── DbContext C
└── custom coordination everywhere
DataArc.EntityFrameworkCore adds an explicit execution layer above EF Core.
Application workflow
↓
DataArc query and command pipelines
↓
Explicit execution-context selection
↓
Registered EF Core DbContext
Concrete DbContext implementations stay inside persistence.
Application code targets public execution-context contracts and chooses exactly where each query or command must run.
var employees = await query
.UseDbExecutionContext<IGoogleDbContext>()
.ReadWhereAsync<Employee>(
employee => employee.Rating > 4.5);The execution boundary is visible, deliberate, and testable.
| Capability | What it solves |
|---|---|
| Execution contexts | Route work to the correct DbContext without exposing concrete persistence classes |
| Query pipelines | Run explicit reads through registered database boundaries |
| Command pipelines | Build coordinated write workflows before execution |
| Bulk operations | Process large prepared collections through the same execution model |
| Parallel execution | Run independent context operations concurrently |
| Structured results | Inspect success, exceptions, and affected-record counts consistently |
| Database generation | Create databases and generate reviewable SQL scripts from EF Core models |
| Architectural flexibility | Use DataArc inside services, repositories, modular monoliths, bounded contexts, CQRS, or Clean Architecture |
DataArc does not require a repository per table or a command/query class for every database permutation.
It provides the execution infrastructure. Your application keeps the business intent.
Create one command, target multiple execution contexts, and choose the execution mode.
var commandBuilder = await _commandFactory
.CreateCommandBuilderAsync();
commandBuilder
.UseDbExecutionContext<IGoogleDbContext>()
.AddBulk(employees, batchSize);
commandBuilder
.UseDbExecutionContext<IMicrosoftDbContext>()
.AddBulk(employees, batchSize);
commandBuilder
.UseDbExecutionContext<IOpenAiDbContext>()
.AddBulk(employees, batchSize);
var command = await commandBuilder.BuildAsync();
var result = await command.ExecuteParallelAsync();
if (!result.Success)
{
throw new InvalidOperationException(
"Employee distribution failed.",
result.Exception);
}
return result.TotalAffected;One application command
├── GoogleDbContext
├── MicrosoftDbContext
└── OpenAiDbContext
↓
structured execution result
Application code depends on an execution boundary:
public interface IGoogleDbContext : IExecutionContext
{
DbSet<Employer>? Employer { get; set; }
DbSet<Employee>? Employee { get; set; }
}The concrete EF Core implementation remains internal:
internal sealed class GoogleDbContext :
DbContext,
IGoogleDbContext
{
public GoogleDbContext(
DbContextOptions<GoogleDbContext> options)
: base(options)
{
}
public DbSet<Employer>? Employer { get; set; }
public DbSet<Employee>? Employee { get; set; }
}Registration maps the public contract to the implementation:
services.AddDataArcCore();
services.ConfigureDataArc(dataArc =>
{
dataArc.UseEntityFrameworkCore(ef =>
{
ef.AddDbExecutionContext<
IGoogleDbContext,
GoogleDbContext>(
options =>
options.UseSqlServer(
googleConnectionString));
});
});Generate a database from the current EF Core model and retain reviewable SQL scripts.
var database = _databaseFactory
.CreateDatabaseBuilder()
.IncludeDbContext<GoogleDbContext>()
.Build(
generateScripts: true,
applyChanges: true);
database.ExecuteCreate();The same builder model supports database deletion:
database.ExecuteDrop();This is useful for:
- repeatable development environments;
- integration tests;
- demos;
- empty-database onboarding;
- reviewed baseline SQL generation.
For existing production databases, use an appropriate incremental schema-migration strategy.
This repository demonstrates DataArc.EntityFrameworkCore across four isolated SQL Server database boundaries:
SAS_GoogleDb
SAS_MicrosoftDb
SAS_OpenAiDb
SAS_Db
The demo:
- creates and seeds the databases;
- reads employees through an explicit source context;
- applies salary-adjustment rules;
- bulk-writes prepared data to independent targets;
- executes target operations in parallel;
- queries each database independently;
- consolidates the read model in application code;
- returns structured execution results.
No cross-database EF Core join is used.
Each database remains its own persistence boundary.
The included BenchmarkDotNet project exercises parallel bulk insertion across four EF Core contexts.
| Total inserted records | Mean |
|---|---|
| 250,000 | 560.5 ms |
| 500,000 | 1,077.9 ms |
| 1,000,000 | 1,964.6 ms |
These results are workload-specific, not a universal performance guarantee.
Hardware, SQL Server configuration, schema design, indexes, batch size, runtime version, and database state all affect performance.
The important execution shape is:
one explicit command pipeline
+ four EF Core contexts
+ parallel execution
+ structured result handling
Update the connection strings in the host appsettings.json:
{
"ConnectionStrings": {
"GoogleDb": "Server=YOUR_SERVER;Database=SAS_GoogleDb;Integrated Security=true;TrustServerCertificate=True;",
"MicrosoftDb": "Server=YOUR_SERVER;Database=SAS_MicrosoftDb;Integrated Security=true;TrustServerCertificate=True;",
"OpenAiDb": "Server=YOUR_SERVER;Database=SAS_OpenAiDb;Integrated Security=true;TrustServerCertificate=True;",
"SolidArcDb": "Server=YOUR_SERVER;Database=SAS_Db;Integrated Security=true;TrustServerCertificate=True;"
}
}dotnet run --framework net8.0The demo multi-targets .NET 6, 7, 8, 9, and 10.
The demo recreates its configured databases. Use disposable development databases only.
The full documentation covers:
- getting started;
- compatibility;
- execution contexts;
- query pipelines;
- command pipelines;
- bulk and parallel operations;
- transactional workflows;
- structured execution results;
- database and script generation;
- trial and licensing.
DataArc.EntityFrameworkCore is intended for applications where EF Core execution must be coordinated across controlled persistence boundaries.
It fits naturally inside:
- modular monoliths;
- bounded-context systems;
- Clean Architecture;
- CQRS-style applications;
- background workers;
- batch-processing systems;
- data synchronisation workflows;
- architecture-remediation projects.
It is not intended to bypass service ownership or encourage unrelated services to access each other's private databases.
The goal is explicit coordination—not hidden coupling.
Use the trial against a real workload and measure whether DataArc reduces:
- custom EF Core coordination code;
- repository and handler sprawl;
- duplicated execution logic;
- ambiguity around context selection;
- bulk-processing complexity;
- result-handling inconsistency.
EF Core
owns database access
DataArc.EntityFrameworkCore
owns explicit execution
Keep your contexts separate. Make execution visible. Coordinate the workflow.