perf(central): set-based ingest, aligned partition purge, KPI query shapes, EF hygiene
This commit is contained in:
@@ -26,6 +26,22 @@ public static class ServiceCollectionExtensions
|
||||
// registers IDataProtectionProvider as a singleton; resolving it here does not recurse
|
||||
// because key-ring loading is lazy (first Protect/Unprotect), not triggered by
|
||||
// CreateProtector during model building.
|
||||
//
|
||||
// POOLING IS DELIBERATELY NOT USED (WP2.2 — verified, not overlooked).
|
||||
// AddDbContextPool requires a context with a SINGLE public constructor taking
|
||||
// only DbContextOptions<TContext>; EF Core constructs pooled instances through
|
||||
// its own activator and cannot supply anything else. ScadaBridgeDbContext has
|
||||
// two public constructors and the runtime one takes IDataProtectionProvider,
|
||||
// because the encrypting value converter for secret-bearing columns is built
|
||||
// during OnModelCreating from that provider. Worse, the model itself DIFFERS
|
||||
// between the two constructors (no provider ⇒ no encrypting converter), so a
|
||||
// pooled activator would silently produce a context that reads secret columns
|
||||
// as ciphertext. Making this poolable means moving the protector out of the
|
||||
// constructor and into a DbContextOptions extension — a change to the
|
||||
// secrets-at-rest path, which is not a performance refactor. The registration
|
||||
// below (a scoped factory overriding AddDbContext's activator) is what makes
|
||||
// the provider reach the context at all, and it also bypasses pooling by
|
||||
// construction. Revisit only alongside a deliberate secrets-plumbing change.
|
||||
services.AddDbContext<ScadaBridgeDbContext>((serviceProvider, options) =>
|
||||
{
|
||||
options.UseSqlServer(
|
||||
|
||||
Reference in New Issue
Block a user