using Microsoft.Data.SqlClient; using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; namespace XLAB2.Infrastructure; internal static class SqlAsync { public static async Task> QueryAsync( this SqlConnection connection, string commandText, Func map, Action configureCommand = null, CancellationToken cancellationToken = default) { if (connection == null) { throw new ArgumentNullException(nameof(connection)); } if (map == null) { throw new ArgumentNullException(nameof(map)); } using var command = connection.CreateCommand(); command.CommandText = commandText; configureCommand?.Invoke(command); using var reader = await command.ExecuteReaderAsync(cancellationToken).ConfigureAwait(false); var items = new List(); while (await reader.ReadAsync(cancellationToken).ConfigureAwait(false)) { items.Add(map(reader)); } return items; } public static async Task> QueryAsync( this SqlConnection connection, SqlTransaction transaction, string commandText, Func map, Action configureCommand = null, CancellationToken cancellationToken = default) { if (connection == null) { throw new ArgumentNullException(nameof(connection)); } if (map == null) { throw new ArgumentNullException(nameof(map)); } using var command = new SqlCommand(commandText, connection, transaction); configureCommand?.Invoke(command); using var reader = await command.ExecuteReaderAsync(cancellationToken).ConfigureAwait(false); var items = new List(); while (await reader.ReadAsync(cancellationToken).ConfigureAwait(false)) { items.Add(map(reader)); } return items; } public static async Task ExecuteNonQueryAsync( this SqlConnection connection, string commandText, Action configureCommand = null, CancellationToken cancellationToken = default) { if (connection == null) { throw new ArgumentNullException(nameof(connection)); } using var command = connection.CreateCommand(); command.CommandText = commandText; configureCommand?.Invoke(command); return await command.ExecuteNonQueryAsync(cancellationToken).ConfigureAwait(false); } public static async Task ExecuteNonQueryAsync( this SqlConnection connection, SqlTransaction transaction, string commandText, Action configureCommand = null, CancellationToken cancellationToken = default) { if (connection == null) { throw new ArgumentNullException(nameof(connection)); } using var command = new SqlCommand(commandText, connection, transaction); configureCommand?.Invoke(command); return await command.ExecuteNonQueryAsync(cancellationToken).ConfigureAwait(false); } public static async Task ExecuteScalarAsync( this SqlConnection connection, string commandText, Action configureCommand = null, CancellationToken cancellationToken = default) { if (connection == null) { throw new ArgumentNullException(nameof(connection)); } using var command = connection.CreateCommand(); command.CommandText = commandText; configureCommand?.Invoke(command); var result = await command.ExecuteScalarAsync(cancellationToken).ConfigureAwait(false); if (result == null || result is DBNull) { return default!; } return (T)Convert.ChangeType(result, typeof(T)); } public static async Task ExecuteScalarAsync( this SqlConnection connection, SqlTransaction transaction, string commandText, Action configureCommand = null, CancellationToken cancellationToken = default) { if (connection == null) { throw new ArgumentNullException(nameof(connection)); } using var command = new SqlCommand(commandText, connection, transaction); configureCommand?.Invoke(command); var result = await command.ExecuteScalarAsync(cancellationToken).ConfigureAwait(false); if (result == null || result is DBNull) { return default!; } return (T)Convert.ChangeType(result, typeof(T)); } public static async Task> QueryOpenConnectionAsync( this IDatabaseConnectionFactory connectionFactory, string commandText, Func map, Action configureCommand = null, CancellationToken cancellationToken = default) { if (connectionFactory == null) { throw new ArgumentNullException(nameof(connectionFactory)); } await using var connection = await connectionFactory.OpenConnectionAsync(cancellationToken).ConfigureAwait(false); return await connection.QueryAsync(commandText, map, configureCommand, cancellationToken).ConfigureAwait(false); } }