using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.Linq; using System.Text; namespace DFEngine.Database { /// /// Class to call stored procedures from a SQL database. /// public class StoredProcedure : Object { /// /// The underlying SQL command object. /// private readonly SqlCommand command; /// /// The name of the stored procedure. /// private readonly string name; /// /// Parameters that will be modified when the command is executed. /// private readonly Dictionary outputParameters; /// /// Creates a new instance of the class. /// /// The name of the stored procedure. /// The connection that the procedure is being ran on. public StoredProcedure(string name, SqlConnection connection) { this.name = name; command = connection.CreateCommand(); command.CommandType = CommandType.StoredProcedure; outputParameters = new Dictionary(); } /// /// Adds an output parameter to the procedure. /// /// The type of the value. /// The name of the parameter. /// The data length of the value. public void AddOutput(string name, int size = -1) { if (outputParameters.ContainsKey(name)) { return; } var parameter = command.Parameters.AddWithValue(name, default(T)); parameter.Direction = ParameterDirection.Output; if (typeof(T) == typeof(byte[])) { parameter.DbType = DbType.Binary; } if (size != -1) { parameter.Size = size; } outputParameters.Add(name, default(T)); } /// /// Adds a parameter to the procedure. /// /// The name of the parameter. /// The value to pass to the procedure. /// The data length of the value. public void AddParameter(string name, object value, int size = -1) { var parameter = command.Parameters.AddWithValue(name, value ?? DBNull.Value); if (size != -1) { parameter.Size = size; } } /// /// Finalizes the output variables before returning from the query. /// public void FinalizeOutput() { for (var i = 0; i < outputParameters.Count; i++) { var output = outputParameters.ElementAt(i); outputParameters[output.Key] = command.Parameters[output.Key].Value; } } /// /// Gets a value from the output parameters. /// /// The type of the value. /// The name of the parameter. public T GetOutput(string name) { if (!outputParameters.ContainsKey(name) || outputParameters[name] is DBNull) { return default(T); } return (T)outputParameters[name]; } /// /// Runs the command. /// public StoredProcedure Run() { SetCommandText(); command.ExecuteNonQuery(); FinalizeOutput(); return this; } /// /// Runs the command and returns an instance. /// public SqlDataReader RunReader() { SetCommandText(); var reader = command.ExecuteReader(); FinalizeOutput(); return reader; } /// /// Sets the command's text. /// public void SetCommandText() { // command.CommandText = $"{{call {name}"; command.CommandText = $"{name}"; // if (command.Parameters.Count > 0) // { // command.CommandText += "("; // // for (var i = 0; i < command.Parameters.Count; i++) // { // command.CommandText += "?, "; // } // // command.CommandText = command.CommandText.Substring(0, command.CommandText.LastIndexOf(", ", StringComparison.Ordinal)); // command.CommandText += ")"; // } // command.CommandText += "}"; } /// /// Destroys the instance. /// protected override void Destroy() { command.Dispose(); } } }