diff --git a/.github/upgrades/scenarios/new-dotnet-version_02bc64/scenario.json b/.github/upgrades/scenarios/new-dotnet-version_02bc64/scenario.json
index 4c5cad27..197127c6 100644
--- a/.github/upgrades/scenarios/new-dotnet-version_02bc64/scenario.json
+++ b/.github/upgrades/scenarios/new-dotnet-version_02bc64/scenario.json
@@ -3,7 +3,7 @@
"operationId": "02bc6448-a69d-4ff4-a0ec-0db07ec3a09a",
"description": "Upgrade solution or project to new version of .NET",
"startTime": "2026-03-05T22:18:32.3921759Z",
- "lastUpdateTime": "2026-03-10T17:00:26.858894Z",
+ "lastUpdateTime": "2026-03-10T17:43:12.8279563Z",
"stage": "Execution",
"properties": {},
"folderPath": ""
diff --git a/Jellyfin.Server/Jellyfin.Server.csproj.user b/Jellyfin.Server/Jellyfin.Server.csproj.user
index 55f2b8df..bd1700e6 100644
--- a/Jellyfin.Server/Jellyfin.Server.csproj.user
+++ b/Jellyfin.Server/Jellyfin.Server.csproj.user
@@ -1,6 +1,6 @@
- D:\Projects\pgsql-jellyfin\Jellyfin.Server\Properties\PublishProfiles\SelfContained-Linux-x64.pubxml
+ D:\Projects\pgsql-jellyfin\Jellyfin.Server\Properties\PublishProfiles\SelfContained-Win-x64.pubxml
\ No newline at end of file
diff --git a/src/Jellyfin.Database/Jellyfin.Database.Providers.Postgres/PostgresDatabaseProvider.cs b/src/Jellyfin.Database/Jellyfin.Database.Providers.Postgres/PostgresDatabaseProvider.cs
index 8b3427ec..f33acbb1 100644
--- a/src/Jellyfin.Database/Jellyfin.Database.Providers.Postgres/PostgresDatabaseProvider.cs
+++ b/src/Jellyfin.Database/Jellyfin.Database.Providers.Postgres/PostgresDatabaseProvider.cs
@@ -297,30 +297,81 @@ public sealed class PostgresDatabaseProvider : IJellyfinDatabaseProvider
/// A task representing the asynchronous operation.
public async Task EnsureDatabaseExistsAsync(DatabaseConfigurationOptions databaseConfiguration, CancellationToken cancellationToken = default)
{
- static T? GetOption(ICollection? options, string key, Func converter, Func? defaultValue = null)
- {
- if (options is null)
- {
- return defaultValue is not null ? defaultValue() : default;
- }
-
- var value = options.FirstOrDefault(e => e.Key.Equals(key, StringComparison.OrdinalIgnoreCase));
- if (value is null)
- {
- return defaultValue is not null ? defaultValue() : default;
- }
-
- return converter(value.Value);
- }
-
var customOptions = databaseConfiguration.CustomProviderOptions?.Options;
- var host = GetOption(customOptions, "host", e => e, () => "localhost")!;
- var port = GetOption(customOptions, "port", int.Parse, () => 5432);
- var database = GetOption(customOptions, "database", e => e, () => "jellyfin")!;
- var username = GetOption(customOptions, "username", e => e, () => "jellyfin")!;
- var password = GetOption(customOptions, "password", e => e, () => string.Empty)!;
- var timeout = GetOption(customOptions, "connection-timeout", int.Parse, () => 15);
+ // Start with connection string if provided, then override with individual options
+ NpgsqlConnectionStringBuilder connectionBuilder;
+
+ if (!string.IsNullOrWhiteSpace(databaseConfiguration.CustomProviderOptions?.ConnectionString))
+ {
+ // Parse the existing connection string to get all parameters
+ connectionBuilder = new NpgsqlConnectionStringBuilder(databaseConfiguration.CustomProviderOptions.ConnectionString);
+ logger.LogDebug("EnsureDatabaseExists: Using ConnectionString from configuration as base");
+ }
+ else
+ {
+ // Start with defaults
+ connectionBuilder = new NpgsqlConnectionStringBuilder
+ {
+ Host = "localhost",
+ Port = 5432,
+ Database = "jellyfin",
+ Username = "jellyfin",
+ Password = string.Empty,
+ Timeout = 15
+ };
+ logger.LogDebug("EnsureDatabaseExists: Using default connection parameters");
+ }
+
+ // Override with individual options if provided (these take precedence over ConnectionString)
+ if (customOptions is not null && customOptions.Count > 0)
+ {
+ var hostOpt = customOptions.FirstOrDefault(e => e.Key.Equals("host", StringComparison.OrdinalIgnoreCase));
+ if (hostOpt is not null)
+ {
+ connectionBuilder.Host = hostOpt.Value;
+ }
+
+ var portOpt = customOptions.FirstOrDefault(e => e.Key.Equals("port", StringComparison.OrdinalIgnoreCase));
+ if (portOpt is not null && int.TryParse(portOpt.Value, out var portValue))
+ {
+ connectionBuilder.Port = portValue;
+ }
+
+ var databaseOpt = customOptions.FirstOrDefault(e => e.Key.Equals("database", StringComparison.OrdinalIgnoreCase));
+ if (databaseOpt is not null)
+ {
+ connectionBuilder.Database = databaseOpt.Value;
+ }
+
+ var usernameOpt = customOptions.FirstOrDefault(e => e.Key.Equals("username", StringComparison.OrdinalIgnoreCase));
+ if (usernameOpt is not null)
+ {
+ connectionBuilder.Username = usernameOpt.Value;
+ }
+
+ var passwordOpt = customOptions.FirstOrDefault(e => e.Key.Equals("password", StringComparison.OrdinalIgnoreCase));
+ if (passwordOpt is not null)
+ {
+ connectionBuilder.Password = passwordOpt.Value;
+ }
+
+ var timeoutOpt = customOptions.FirstOrDefault(e => e.Key.Equals("connection-timeout", StringComparison.OrdinalIgnoreCase));
+ if (timeoutOpt is not null && int.TryParse(timeoutOpt.Value, out var timeoutValue))
+ {
+ connectionBuilder.Timeout = timeoutValue;
+ }
+
+ logger.LogDebug("EnsureDatabaseExists: Applied individual option overrides");
+ }
+
+ // Extract final values from builder (ensure non-null for parameters)
+ var host = connectionBuilder.Host ?? "localhost";
+ var port = connectionBuilder.Port;
+ var database = connectionBuilder.Database ?? "jellyfin";
+ var username = connectionBuilder.Username ?? "jellyfin";
+ var password = connectionBuilder.Password ?? string.Empty;
+ var timeout = connectionBuilder.Timeout;
// Connect to 'postgres' maintenance database to check if target database exists
var maintenanceConnectionBuilder = new NpgsqlConnectionStringBuilder