Andrey Busik
Andrey Busik

Reputation: 441

Eliminate code duplication (Work with DB)

I've coded a dll to execute SQL commands. And I have some code duplication in my public methods. Is there some way to avoid code duplication?

Method 1:

    public Object ExecuteScalar(String command)
    {
        using (SqlConnection connection = new SqlConnection(connectionString))
        {
            SqlCommand commandScalar = GetSqlCommand(strCommand: command);

            object result = new object();
            using (commandScalar)
            {
                try
                {
                    connection.StatisticsEnabled = statisticsEnabled;
                    connection.Open();
                    result = commandScalar.ExecuteScalar();
                }
                catch (Exception exception)
                {
                    throw new Exception(String.Format("Не удалось выполнить команду: {0}", commandScalar.CommandText), exception);
                }
                finally
                {
                    connection.Close();
                }
            }
            return result;

            if (connection.StatisticsEnabled)
                AddDictionary(connection.RetrieveStatistics());

            return result;
        }
    }

Method 2:

    public void ExecuteNonQuery(String command, List<SqlParameter> lsParams = null)
    {
        using (SqlConnection connection = new SqlConnection(connectionString))
        {
            SqlCommand commandNonQuery = GetSqlCommand(strCommand: command, lsParams: lsParams, log: logger);

            using(commandNonQuery)
            {
                try
                {
                    connection.StatisticsEnabled = statisticsEnabled;
                    connection.Open();
                    commandNonQuery.ExecuteNonQuery();
                }
                catch (Exception exception)
                {
                    throw new Exception(String.Format("Не удалось выполнить команду: {0}", commandNonQuery.CommandText), exception);
                }
                finally
                {
                    connection.Close();
                }
            }

            if (connection.StatisticsEnabled)
                AddDictionary(connection.RetrieveStatistics());
        }
    }

Method 3:

    public List<IDataRecord> ExecuteReader(String strCommand, List<SqlParameter> lsParams = null)
    {
        using (SqlConnection connection = new SqlConnection(connectionString))
        {
            SqlCommand sqlCommandRead = GetSqlCommand(strCommand: strCommand, lsParams: lsParams, log: logger);

            List<IDataRecord> lsDataRecord = new List<IDataRecord>();
            using (sqlCommandRead)
            {
                try
                {
                    connection.StatisticsEnabled = statisticsEnabled;
                    connection.Open();

                    using (SqlDataReader sqlDataReader = sqlCommandRead.ExecuteReader())
                    {
                        while (sqlDataReader.Read())
                        {
                            lsDataRecord.Add((IDataRecord)sqlDataReader);
                        }
                    }
                }
                catch (Exception exception)
                {
                    throw new Exception(String.Format("Не удалось выполнить команду: {0}", sqlCommandRead.CommandText), exception);
                }
                finally
                {
                    connection.Close();
                }
            }

            if (connection.StatisticsEnabled)
                this.AddDictionary(connection.RetrieveStatistics());

            return lsDataRecord;
        }
    }

Method that generates SQL command to execute:

    private static SqlCommand GetSqlCommand(string strCommand, List<SqlParameter> lsParams = null, Logger log = null)
    {
        lsParams = null ?? new List<SqlParameter>(); 
        log = null ?? LogManager.GetLogger("noname");

        if (strCommand == null || strCommand == "")
        {
            throw new ArgumentException("Передан пустой (или null) текст команды.", "strCommand");
        }

        int parametersRequired = strCommand.Split('@').Length - 1;
        if (parametersRequired != lsParams.Count)
        {
            String strParameters = null;
            foreach (var item in lsParams)
            {
                strParameters += item.ParameterName + " : " + item.Value + "\n";
            }
            strParameters = null ?? "No parameters";
            throw new ArgumentException(String.Format("При формировании SQL - команды выявлено, что число требуемых параметров: {0} не соответствует числу переданных: {1}\n"
                + "Команда:\n{2}\nПараметры:\n{3}", parametersRequired, lsParams.Count, strCommand, strParameters), "lsParams");
        }

        SqlCommand sqlCommand = new SqlCommand(strCommand);

        foreach (var item in lsParams)
        {
            sqlCommand.Parameters.Add(item);
        }

        return sqlCommand;
    }

Upvotes: 0

Views: 99

Answers (1)

Aleksei Semidotskii
Aleksei Semidotskii

Reputation: 1455

public class SqlHelper
{
    private readonly bool statisticsEnabled;

    public SqlHelper(bool statisticsEnabled)
    {
        this.statisticsEnabled = statisticsEnabled;
    }

    public T ExecuteSqalar<T>(SqlCommand command)
    {
        return Execute(command, c => (T) c.ExecuteScalar());
    }

    public void ExecuteNonQuery(SqlCommand command)
    {
        Execute(command, c => c.ExecuteNonQuery());
    }

    public List<IDataRecord> ExecuteReader(SqlCommand command)
    {
        return Execute<List<IDataRecord>>(command, c =>
        {
            var lsDataRecord = new List<IDataRecord>();
            using (SqlDataReader sqlDataReader = command.ExecuteReader())
            {
                while (sqlDataReader.Read())
                {
                    lsDataRecord.Add(sqlDataReader);
                }
            }
        });
    }

    public T Execute<T>(SqlCommand command, Func<SqlCommand, T> processFunction)
    {
        using (var connection = new SqlConnection("CONNECTION_STRING"))
        {
            object result = new object();
            using (command)
            {
                try
                {
                    connection.StatisticsEnabled = statisticsEnabled;
                    connection.Open();
                    result = processFunction(command);
                }
                catch (Exception exception)
                {
                    throw new Exception(String.Format("Не удалось выполнить команду: {0}",     command.CommandText), exception);
                }
                finally
                {
                    connection.Close();
                }
            }

            if (connection.StatisticsEnabled)
                AddDictionary(connection.RetrieveStatistics());

            return (T)result;
        }
    }

    private void AddDictionary(IDictionary retrieveStatistics)
    {
        // TODO:
    }

}

Upvotes: 1

Related Questions