diff --git a/ZB.MOM.WW.Health/src/ZB.MOM.WW.Health.EntityFrameworkCore/DatabaseHealthCheck.cs b/ZB.MOM.WW.Health/src/ZB.MOM.WW.Health.EntityFrameworkCore/DatabaseHealthCheck.cs
new file mode 100644
index 0000000..172c041
--- /dev/null
+++ b/ZB.MOM.WW.Health/src/ZB.MOM.WW.Health.EntityFrameworkCore/DatabaseHealthCheck.cs
@@ -0,0 +1,102 @@
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Diagnostics.HealthChecks;
+
+namespace ZB.MOM.WW.Health.EntityFrameworkCore;
+
+///
+/// Health check that verifies database reachability through an EF Core .
+///
+///
+///
+/// The default probe calls
+///
+/// (the ScadaBridge pattern): when it returns true,
+/// when it returns false or throws. Supplying
+/// swaps in a stricter query-based probe
+/// (the OtOpcUa "query Deployments" pattern): the result is
+/// unless the delegate throws, in which case it is . No exception
+/// escapes .
+///
+///
+/// The context is resolved from the application : an
+/// is used when one is registered (each probe gets a fresh,
+/// disposed context); otherwise a scoped is resolved from a new DI
+/// scope. Recommended registration tag: ZbHealthTags.Ready (applied by the registrant).
+///
+///
+/// The EF Core to probe.
+public sealed class DatabaseHealthCheck : IHealthCheck
+ where TContext : DbContext
+{
+ private readonly IServiceProvider _serviceProvider;
+ private readonly DatabaseHealthCheckOptions _options;
+
+ /// Initializes a new .
+ ///
+ /// Application service provider used to resolve — preferring a
+ /// registered , otherwise a scoped instance.
+ ///
+ ///
+ /// Probe override and timeout. When null, the default CanConnectAsync probe with a
+ /// 10 s timeout is used.
+ ///
+ public DatabaseHealthCheck(
+ IServiceProvider serviceProvider,
+ DatabaseHealthCheckOptions? options = null)
+ {
+ _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));
+ _options = options ?? new DatabaseHealthCheckOptions();
+ }
+
+ ///
+ public async Task CheckHealthAsync(
+ HealthCheckContext context,
+ CancellationToken cancellationToken = default)
+ {
+ using var timeoutCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
+ timeoutCts.CancelAfter(_options.Timeout);
+
+ try
+ {
+ return await ProbeAsync(timeoutCts.Token).ConfigureAwait(false);
+ }
+ catch (OperationCanceledException ex)
+ when (timeoutCts.IsCancellationRequested && !cancellationToken.IsCancellationRequested)
+ {
+ return HealthCheckResult.Unhealthy($"Database probe timed out after {_options.Timeout}.", ex);
+ }
+ catch (Exception ex)
+ {
+ return HealthCheckResult.Unhealthy("Database connection failed.", ex);
+ }
+ }
+
+ private async Task ProbeAsync(CancellationToken cancellationToken)
+ {
+ var factory = _serviceProvider.GetService>();
+ if (factory is not null)
+ {
+ await using var db = await factory.CreateDbContextAsync(cancellationToken).ConfigureAwait(false);
+ return await RunProbeAsync(db, cancellationToken).ConfigureAwait(false);
+ }
+
+ await using var scope = _serviceProvider.CreateAsyncScope();
+ var scoped = scope.ServiceProvider.GetRequiredService();
+ return await RunProbeAsync(scoped, cancellationToken).ConfigureAwait(false);
+ }
+
+ private async Task RunProbeAsync(TContext db, CancellationToken cancellationToken)
+ {
+ if (_options.ProbeQuery is { } probeQuery)
+ {
+ await probeQuery(db, cancellationToken).ConfigureAwait(false);
+ return HealthCheckResult.Healthy("Database query probe succeeded.");
+ }
+
+ var canConnect = await db.Database.CanConnectAsync(cancellationToken).ConfigureAwait(false);
+ return canConnect
+ ? HealthCheckResult.Healthy("Database connection is available.")
+ : HealthCheckResult.Unhealthy("Database connection failed.");
+ }
+}
diff --git a/ZB.MOM.WW.Health/src/ZB.MOM.WW.Health.EntityFrameworkCore/DatabaseHealthCheckOptions.cs b/ZB.MOM.WW.Health/src/ZB.MOM.WW.Health.EntityFrameworkCore/DatabaseHealthCheckOptions.cs
new file mode 100644
index 0000000..66bb471
--- /dev/null
+++ b/ZB.MOM.WW.Health/src/ZB.MOM.WW.Health.EntityFrameworkCore/DatabaseHealthCheckOptions.cs
@@ -0,0 +1,28 @@
+using Microsoft.EntityFrameworkCore;
+
+namespace ZB.MOM.WW.Health.EntityFrameworkCore;
+
+///
+/// Options for .
+///
+/// The EF Core the probe runs against.
+public sealed class DatabaseHealthCheckOptions
+ where TContext : DbContext
+{
+ ///
+ /// Optional query-based probe that overrides the default
+ ///
+ /// reachability check with stricter, query-level validation (the OtOpcUa "query Deployments"
+ /// pattern). Throw to signal failure; return normally to signal success.
+ ///
+ ///
+ /// Example: (db, ct) => db.Deployments.AsNoTracking().Take(1).ToListAsync(ct).
+ /// When null, the default CanConnectAsync probe is used.
+ ///
+ public Func? ProbeQuery { get; set; }
+
+ ///
+ /// Maximum time the probe may run before it is treated as a failure. Defaults to 10 seconds.
+ ///
+ public TimeSpan Timeout { get; set; } = TimeSpan.FromSeconds(10);
+}