Asset DbContext and Object Sets
Summary
Source-backed description of AssetDbContext and a verified inventory of its seven object sets — the persistence surface of the Asset bounded context.
Audience
Backend engineers, database reviewers, architects, QA, support, operations, security reviewers, and product owners.
Overview
AssetDbContext is the single EF Core DbContext for the Asset Service. It owns a dedicated logical schema, exposes seven object sets, and overrides SaveChangesAsync to dispatch domain events to the outbox before committing. All persistence for the bounded context flows through it.
Confirmed persistence behavior
AssetDbContext (AssetDbContext : DbContext, in Infrastructure/AssetDbContext.cs):
- Constructor takes
DbContextOptionsplusITenantContext; the tenant context supplies the current tenant id and super-admin flag used by the global query filters. CompatIdStoreGeneratedis aprotected virtual bool(defaulttrue) controlling whetherCompatIdis a database identity column at runtime. The backfill subclass overrides it tofalseso migrated identifiers are inserted verbatim. See Compatibility Identity Storage.- Default schema is set via
HasDefaultSchema(...)to the Asset bounded-context schema (the physical qualifier is redacted here). SaveChangesAsyncoverride dispatches the aggregate's domain events to outbox rows — mapping six asset domain events to contract integration events and running theEnsureCompletecompleteness guard — and then calls the base save, all in one transaction.- Provider: Npgsql PostgreSQL on EF Core 8, with legacy timestamp behavior enabled.
- Global query filters apply to five of the seven object sets (
IsSuperAdmin || TenantId == CurrentTenantId); the two messaging sets are unfiltered.
Object-set inventory
| # | DbSet property | CLR type | Persistence purpose | Classification | Aggregate ownership | Tenant scope | Query filter | Key | Key relationships | Source |
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | Assets | Asset (aggregate root) | Canonical asset record with owned value columns and lifecycle state | Tenant-domain (aggregate root) | Root | Tenant-scoped | Yes | Guid Id | Parent of history and document-reference children | Domain/Asset/Asset.cs |
| 2 | AssetAssignmentHistory | AssetAssignmentHistory (entity) | Append-only lifecycle/assignment log | Aggregate child | Owned by Asset | Tenant-scoped | Yes | Guid Id (value-generated-never) | FK AssetId → Assets (cascade, required) | Domain/Asset/Asset.cs |
| 3 | AssetDocumentReferences | AssetDocumentReference (entity) | Pointer/metadata for externally-stored documents | Aggregate child | Owned by Asset | Tenant-scoped | Yes | Guid Id (value-generated-never) | FK AssetId → Assets (cascade, required) | Domain/Asset/Asset.cs |
| 4 | AuditLogs | AssetAuditLog (infrastructure) | Append-only audit evidence | Audit (evidence) | Independent | Tenant-scoped | Yes | Guid Id | EntityId is a string reference (not a FK) | Infrastructure/AssetDbContext.cs |
| 5 | TimelineEntries | AssetTimeline (infrastructure) | Append-only human-readable timeline | Timeline (evidence) | Independent | Tenant-scoped | Yes | Guid Id | EntityId is a string reference (not a FK) | Infrastructure/AssetDbContext.cs |
| 6 | ProcessedEvents | ProcessedIntegrationEvent (infrastructure) | Inbound idempotency ledger (modeled, not yet consumed) | Processed-event (messaging) | Independent | Not tenant-filtered | No | Guid Id | Unique index on EventId | Infrastructure/AssetDbContext.cs |
| 7 | OutboxMessages | OutboxMessage (shared kernel) | Outbound integration-event staging | Outbox (messaging) | Independent | Not tenant-filtered | No | Guid Id | Unique index on EventId | shared-kernel |
Verified totals
- 7 object sets mapping to 7 physical tables.
- 5 tenant-filtered sets (Assets, history, document references, audit, timeline); 2 non-filtered sets (outbox, processed-event).
- 1 aggregate root (Assets); 2 aggregate children (history, document references).
- 2 evidence sets (audit, timeline); 2 messaging sets (outbox, processed-event).
- 0 separate compatibility tables — the compatibility identity is a property on the
Assetaggregate, not its own table.
The two messaging sets are deliberately unfiltered because they are infrastructure concerns: the outbox carries envelope-level identifiers, and the processed-event ledger is a modeled foundation that the service does not yet consume at runtime.
Classification
Implemented DbContext with a fully mapped seven-set persistence surface; the processed-event set is Transitional (modeled, unused at runtime).
Requires confirmation
Activation plan for the processed-event idempotency ledger and any future inbound-consumer wiring require confirmation.
Diagram
Related Articles
See Also
Keywords
- Asset persistence
- DbContext and Object Sets
- Draft database documentation
Source References
microservices/src/asset-service/Infrastructure/AssetDbContext.csmicroservices/src/asset-service/Domain/Asset/Asset.csmicroservices/src/asset-service/Infrastructure/Migrations/AssetDbContextModelSnapshot.cs
Revision Information
- Status: Draft
- Last reviewed: 2026-07-17
- Review cycle: Quarterly