Entity Framework Core Skill Sorcha uses EF Core 9+ with PostgreSQL (Npgsql) as the primary relational data store. The codebase implements a layered repository pattern with generic and specialized repositories, soft delete via query filters, and automatic migrations on startup. Quick Start Register DbContext with PostgreSQL // src/Common/Sorcha.Storage.EFCore/Extensions/EFCoreServiceExtensions.cs services . AddDbContext < WalletDbContext
( ( sp , options ) => { var dataSource = sp . GetRequiredService < NpgsqlDataSource
( ) ; options . UseNpgsql ( dataSource , npgsql => { npgsql . EnableRetryOnFailure ( maxRetryCount : 10 , maxRetryDelay : TimeSpan . FromSeconds ( 30 ) , errorCodesToAdd : null ) ; npgsql . MigrationsHistoryTable ( "__EFMigrationsHistory" , "wallet" ) ; } ) ; } ) ; Create a Migration
From project directory containing DbContext
dotnet ef migrations
add
InitialSchema
--project
src/Common/Sorcha.Wallet.Core --startup-project src/Services/Sorcha.Wallet.Service
Apply Migrations Programmatically
// Startup pattern used in Sorcha services
var
pending
=
await
dbContext
.
Database
.
GetPendingMigrationsAsync
(
)
;
if
(
pending
.
Any
(
)
)
await
dbContext
.
Database
.
MigrateAsync
(
)
;
Key Concepts
Concept
Usage
Example
DbContext
Schema definition + change tracking
WalletDbContext
,
TenantDbContext
Repository
Data access abstraction
EFCoreRepository
GetByAddressAsync ( string address , bool includeAddresses = false ) { IQueryable < WalletEntity
query
_context . Wallets ; if ( includeAddresses ) query = query . Include ( w => w . Addresses ) ; return await query . AsNoTracking ( ) . FirstOrDefaultAsync ( w => w . Address == address ) ; } Soft Delete with Filter Bypass // Bypass query filter for admin operations var deleted = await _context . Wallets . IgnoreQueryFilters ( ) . FirstOrDefaultAsync ( w => w . Address == address ) ; See Also patterns - DbContext configuration, entity mapping, query optimization workflows - Migration commands, testing patterns, deployment