Skip to main content

C# and .NET First Verification

The first verification must execute through an ADO.NET provider and reopen the database. A successful generated-library build is necessary but not sufficient.

1. Contract and build

dotnet build -p:UseSharedCompilation=false
dotnet test -p:UseSharedCompilation=false
rg 'Purpose\(|ExecuteForListAsync|ExecuteEntitiesForListAsync' generated

Confirm execution receives only UserContext, and the terminal exists only on the executable wrapper returned by Purpose.

2. SQLite integration

Use a unique database path. Initialize a trusted context with Microsoft.Data.Sqlite, ensure schema, save one audited entity, query it, dispose connections, create a new context, and query again.

[Fact]
public async Task PersistsAndReloadsARecord()
{
await using var fixture = await SqliteFixture.CreateAsync();
var ctx = fixture.Context;

var order = Q.CustomerOrders().Comment("Create verification order")
.Purpose("Verify SQLite persistence").NewEntity(ctx);
order.UpdateOrderNumber("VERIFY-10001");
await order.AuditAs("Create verification fixture").SaveAsync(ctx);

var rows = await Q.CustomerOrders().Comment("Read verification order")
.WithOrderNumberContaining("VERIFY-10001").Purpose("Verify persisted result")
.ExecuteEntitiesForListAsync(ctx);
Assert.Single(rows);
}

Replace illustrative names with the generated contract. Add a reconnect assertion.

3. Negative gates

Prove missing comment/purpose, uninitialized context, missing AuditAs, stale version, unknown dynamic fields/operators, forbidden sorts, invalid ranges/offset/page sizes, and trusted-context override attempts are rejected. Compile-time absence of terminals is preferable where type state applies; runtime cases must throw explicit exceptions.

4. Provider SQL

Capture a masked trace for stable pagination, bound parameters, native COUNT/SUM/GROUP BY, and partition/window per-parent Top-N. Rows, record count, facets, and total must share one normalized active filter.

After SQLite, qualify each intended ADO.NET provider independently. SQL Server support is Feature-level only after the same semantic and governance suite passes; loading an ADO.NET assembly alone is not evidence.

5. Optimistic locking and audit

Load the same entity twice, save the first update with an audit reason, and assert the second save fails as stale. Verify both the immutable runtime mutation event and the separate masked application audit sink.

6. Regeneration

Add a model field, regenerate from scratch, rebuild and rerun tests. Record SDK, generator/runtime/provider versions, model hash, commands, exit codes, native response, and masked SQL trace.