Skip to content

Integration SqlClient Extension

aryehcitron@gmail.com edited this page May 24, 2026 · 5 revisions

The Kronikol.Extensions.SqlClient package adds SQL Server operation tracking to your test diagrams via Microsoft.Data.SqlClient's built-in DiagnosticSource instrumentation. No production code changes required.

Zero production changes. SqlClient emits diagnostic events automatically. This extension subscribes to them globally, so every SqlConnection in the process is tracked.


How It Works

Microsoft.Data.SqlClient publishes DiagnosticSource events under "SqlClientDiagnosticListener". The SqlClientDiagnosticTracker subscribes and handles both modern (WriteCommandBefore/WriteCommandAfter) and legacy (ExecuteReader.Start/ExecuteReader.Stop) event naming patterns. Commands are correlated via OperationId GUID, classified by UnifiedSqlClassifier, and logged to RequestResponseLogger.


Install

dotnet add package Kronikol.Extensions.SqlClient

Setup

Option A — Dependency Injection

services.AddSqlServerTestTracking(options =>
{
    options.Verbosity = SqlTrackingVerbosityLevel.Detailed;
});

Option B — Static (No DI)

SqlClientTestTracking.EnsureTracking(new SqlClientTrackingOptions
{
    Verbosity = SqlTrackingVerbosityLevel.Detailed
});

// In teardown:
SqlClientTestTracking.Reset();

Configuration

Property Default Description
ServiceName "SQL Server" Participant name in diagrams
CallerName "Caller" The caller participant name
Verbosity Detailed Raw, Detailed, or Summarised
CurrentTestInfoFetcher null Returns the current test's name and ID. Required for wrapping approach
HttpContextAccessor null Optional — enables dual-resolution of test identity from HTTP headers
LogSqlText true Include full SQL text in Detailed mode
LogParameters false Include parameter values
DependencyCategory "SqlServer" Controls participant shape/colour
UriScheme "sqlserver" URI scheme in diagram URIs
ExcludedOperations [] Operations to exclude from tracking
SetupVerbosity null Verbosity override for the Setup phase. See Phase-Aware Tracking
ActionVerbosity null Verbosity override for the Action phase. See Phase-Aware Tracking
TrackDuringSetup true When false, tracking is suppressed during Setup
TrackDuringAction true When false, tracking is suppressed during Action
LogResponseContent true Include response data in diagram arrows at all verbosity levels (v2.37.0+)
MaxResponseRows 10 Maximum rows to capture in response content
MaxValueDisplayLength 500 Truncate individual cell values beyond this length
ResponseDetail RowCountAndColumns RowCountOnly, RowCountAndColumns, or FullRows

All options inherit from SqlTrackingOptionsBase.


Verbosity Levels

Level Arrow label URI
Raw Full SQL text sqlserver://host/database
Detailed SELECT FROM Users sqlserver://host/database/Users
Summarised SELECT sqlserver:///database/Users

Response Payload Capture (v2.37.0+)

Response arrows in diagrams now show actual data instead of being empty. The ResponseDetail option controls the level of detail:

ResponseDetail Example output
RowCountOnly 3 rows
RowCountAndColumns (default) 3 rows [Name, Preference, CreatedAt]
FullRows JSON row preview (up to MaxResponseRows)

Set LogResponseContent = false to restore previous empty-arrow behaviour.


Wrapping Alternative (v2.37.0+)

In addition to the zero-change DiagnosticSource approach above, the SqlClient extension also provides a connection-wrapping approach. This is useful when DiagnosticSource instrumentation is unavailable, disabled, or when you need response payload capture from ExecuteReader/ExecuteScalar.

Classes

Class Wraps Purpose
TrackingSqlConnection SqlConnection Intercepts command creation and transaction begin
TrackingSqlCommand SqlCommand Intercepts ExecuteReader, ExecuteNonQuery, ExecuteScalar (sync + async)
TrackingSqlTransaction SqlTransaction Logs BEGIN, COMMIT, ROLLBACK

Extension Method

using Microsoft.Data.SqlClient;
using Kronikol.Extensions.SqlClient;

var connection = new SqlConnection(connectionString)
    .WithTestTracking(new SqlClientTrackingOptions
    {
        ServiceName = "SQL Server",
        Verbosity = SqlTrackingVerbosityLevel.Detailed,
        CurrentTestInfoFetcher = CurrentTestInfo.Fetcher
    });

SqlConnection.WithTestTracking() returns a TrackingSqlConnection (which extends DbConnection), so it works transparently with any code that accepts DbConnection — including Dapper, raw ADO.NET, and DI registrations.

DI Registration

builder.ConfigureTestServices(services =>
{
    services.AddScoped<DbConnection>(sp =>
    {
        var inner = new SqlConnection(connectionString);
        return inner.WithTestTracking(new SqlClientTrackingOptions
        {
            ServiceName = "SQL Server",
            Verbosity = SqlTrackingVerbosityLevel.Detailed,
            CurrentTestInfoFetcher = CurrentTestInfo.Fetcher
        });
    });
});

DiagnosticSource vs Wrapping: The DiagnosticSource approach (Option A/B above) requires zero production code changes but cannot capture response payloads. The wrapping approach captures response data from ExecuteReader and ExecuteScalar, but requires the connection to be wrapped. Choose based on your needs — you can use both in the same project for different connections.

Home


Demo


Getting Started

Common Tasks

Integration Guides

Extensions

Configuration

Features

Reference

Clone this wiki locally