namespace LaaProductionWeb.Data { using LaaProductionWeb.Data.Interfaces; using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.Linq; public class FluentSQL : IFluentSQL { private readonly string connectionString; public FluentSQL(string connectionString) { var connectionStringBuilder = new SqlConnectionStringBuilder(connectionString); this.connectionString = connectionStringBuilder.ToString(); } public FluentSQLCommand CreateCommand(string commandText) => new FluentSQLCommand(this, commandText); internal int ExecuteNonQuery(FluentSQLCommand command) { command.ThrowIfNull(); var rowsAffected = 0; using (var sqlConnection = new SqlConnection(this.connectionString)) { sqlConnection.OpenWithErrorHandling(); using (var sqlCommand = sqlConnection.CreateCommand()) { sqlCommand.CommandText = command.CommandText; sqlCommand.Parameters.AddRange(command.Parameters); rowsAffected = sqlCommand.ExecuteNonQuery(); } } return rowsAffected; } internal IEnumerable ExecuteReader(FluentSQLCommand command, Func expression) { command.ThrowIfNull(); expression.ThrowIfNull(); using (var sqlConnection = new SqlConnection(this.connectionString)) { sqlConnection.OpenWithErrorHandling(); using (var sqlCommand = sqlConnection.CreateCommand()) { sqlCommand.CommandText = command.CommandText; sqlCommand.Parameters.AddRange(command.Parameters); using (FluentSQLReader sqlReader = sqlCommand.ExecuteReader(CommandBehavior.SequentialAccess)) { while (sqlReader.Read()) { yield return expression(sqlReader); } } } } } internal T ExecuteScalar(FluentSQLCommand command, Func expression) { command.ThrowIfNull(); expression.ThrowIfNull(); var scalarResult = default(T); using (var sqlConnection = new SqlConnection(this.connectionString)) { sqlConnection.OpenWithErrorHandling(); using (var sqlCommand = sqlConnection.CreateCommand()) { sqlCommand.CommandText = command.CommandText; sqlCommand.Parameters.AddRange(command.Parameters); var scalarObject = sqlCommand.ExecuteScalar(); if (scalarObject is T scalarValue) { scalarResult = scalarValue; } } } return scalarResult; } internal T FirstOrDefault(FluentSQLCommand command, Func expression) => this .ExecuteReader(command, expression) .FirstOrDefault(); } }