Skip to content

Pragmatic.Persistence.EFCore

EF Core runtime implementation for the Pragmatic persistence stack.

Pragmatic.Persistence.EFCore bridges the gap between Pragmatic entity declarations and a working EF Core data layer. Where Pragmatic.Persistence provides the attributes and interfaces, this package provides the runtime: generated DbContexts, repository implementations, interceptors, the filter pipeline, and bulk operations.

You declare a database, the host says which module lives on it, and you get a fully configured data layer:

// In the host: declare the database…
[PragmaticDatabase(Provider = DatabaseProvider.PostgreSql, ConfigKey = "ConnectionStrings:Sales")]
public sealed class SalesDatabase : PragmaticDatabase;
// …and say which module lives on it. That pairing IS the topology.
[Include<SalesModule, SalesDatabase>]
public sealed class AppHostModule;

You never write a DbContext: the generator emits one per boundary from that pairing, and the generated host registers each of them for you.

The source generator reads each boundary’s entities and produces OnModelCreating with all IEntityTypeConfiguration<T> calls, DbSet properties, interceptor registration, and an Add{Boundary}DbContext() extension method for DI.

Inside a Pragmatic host that is all of it — the generated host registers the DbContexts, the repositories and the query filters before your IStartupStep runs. Wiring it by hand, outside a host, the three calls are:

builder.Services.AddSalesDbContext(options =>
options.UseNpgsql(builder.Configuration.GetConnectionString("Sales")));
builder.Services.AddPragmaticPersistenceRepositories<SalesDbContext>();
builder.Services.AddMyAppQueryFilters();

This package is designed to work alongside Pragmatic.Persistence and the Pragmatic.SourceGenerator analyzer. All three are required for the full generated output.

Terminal window
dotnet add package Pragmatic.Persistence
dotnet add package Pragmatic.Persistence.EFCore

Add the analyzer as a project reference:

<ProjectReference Include="..\Pragmatic.SourceGenerator\src\Pragmatic.SourceGenerator\Pragmatic.SourceGenerator.csproj"
OutputItemType="Analyzer"
ReferenceOutputAssembly="false" />

Each feature below addresses a specific problem in EF Core data-access code. The links lead to detailed guides with examples, generated output, and design rationale.

ProblemSolutionGuide
Every entity needs manual IEntityTypeConfiguration<T>Generated config from [Entity], [Relation.*], [SoftDelete], [ConcurrencyAware]Entity Configuration
DbContext setup is boilerplate (DbSet, OnModelCreating, DI)[PragmaticDatabase] + [Include<TModule, TDatabase>] → complete DbContext generationDbContext Generation
Repository CRUD is the same shape for every entityGenerated repos with CRUD, specs, logic-key helpers, include overloads, bulk methodsRepository Implementation
Timestamps, tenant and ownership fields are easy to forgetAuditingInterceptor, TenantInterceptor, OwnershipInterceptor, SoftDeleteInterceptor run on SaveChangesInterceptors & Runtime
Include() bypasses soft-delete and tenant filtersPragmaticQueryFilterVisitor injects .Where() into navigation expressionsFilter Pipeline
Inserting thousands of records one by one is slowGenerated BulkInsertAsync, BulkUpsertAsync with provider-specific SQLBulk Operations
Adding [SoftDelete] to existing entities needs safe migrationDocumented rollout patterns with data backfill and rollback plansMigration Patterns
Integration tests need a real database with filter setupTest harness with Testcontainers, fake ICurrentUser, filter toggleTesting

GuideWhat You’ll Learn
DbContext Generation[PragmaticDatabase], [Include<,>], DI registration, multi-provider support
Repository ImplementationGenerated repository shape, keyed DI, soft-delete Remove(), IUnitOfWork
Entity ConfigurationProperty mapping, indexes, relationships, inheritance, two-level query filters
Interceptors & Runtimewhere the ID comes from, auditing, tenant, soft-delete and ownership interceptors, value converters
Bulk OperationsBulk insert/update/delete/upsert, provider SQL, concurrency options
Filter PipelineFilterMapComposer, expression visitor, EfCoreQueryExecutor integration
TestingTestcontainers PostgreSQL, fixture setup, fake current user, filter toggles
Migration PatternsSafe rollout for [SoftDelete], [Auditable], and schema-changing attributes

For entity-level concepts (attributes, relationships, queries, mutations), see the Pragmatic.Persistence documentation.

  • .NET 10.0+
  • Microsoft.EntityFrameworkCore 10.0+

Part of the Pragmatic.Design ecosystem.