I've only done C++ and some C# and I am new to MySQL and I don't understand the purpose of the string builder here.
This code is part of a program which is used to extract data from a webpage and insert it into an already existing Word File using bookmarks.
MY CODE
using System.Collections.Generic;
using System.Configuration;
using System.Text;
using MySql.Data.MySqlClient;
namespace ARExtractionLibrary
{
public class DataExtractor
{
#region Attributes
private string _databaseConfig = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
private const int AR_TRACKER_ID = 10;
private const int AR_NUMBER_ID = 3;
#endregion
#region Methods
public Dictionary<string, Field> GetFieldData(int TicketID)
{
MySqlConnection sqlConnection = new MySqlConnection(_databaseConfig);
Dictionary<string, Field> fieldsDictionary = new Dictionary<string, Field>();
StringBuilder queryDefaultFields = new StringBuilder();
queryDefaultFields.Append("SELECT issues.id AS TicketID, issues.subject, issues.description, ");
queryDefaultFields.Append(" CONCAT(users.firstname,' ', users.lastname) as Author");
queryDefaultFields.Append(" FROM issues LEFT JOIN users ON users.id =issues.author_id");
queryDefaultFields.Append(" WHERE issues.id = @TicketID");
StringBuilder queryCustomFields = new StringBuilder();
queryCustomFields.Append("SELECT custom_fields.name, custom_fields.field_format, CONCAT(users.firstname,' ',users.lastname) AS value");
queryCustomFields.Append(" FROM custom_values");
queryCustomFields.Append(" LEFT JOIN custom_fields ON custom_values.custom_field_id = custom_fields.id");
queryCustomFields.Append(" JOIN users ON custom_values.value = users.id");
queryCustomFields.Append(" WHERE custom_values.customized_id = @TicketId");
queryCustomFields.Append(" AND field_format = 'user'");
queryCustomFields.Append(" UNION");
queryCustomFields.Append(" SELECT custom_fields.name, custom_fields.field_format, custom_values.value");
queryCustomFields.Append(" FROM custom_values");
queryCustomFields.Append(" LEFT JOIN custom_fields ON custom_values.custom_field_id = custom_fields.id");
queryCustomFields.Append(" WHERE custom_values.customized_id = @TicketId");
queryCustomFields.Append(" AND field_format <> 'user'");
sqlConnection.Open();
//First query
MySqlCommand sqlCommand = null;
sqlCommand = new MySqlCommand(queryDefaultFields.ToString(), sqlConnection);
sqlCommand.Parameters.AddWithValue("@TicketId", TicketID);
MySqlDataReader sqlDataReader = sqlCommand.ExecuteReader();
while (sqlDataReader.Read())
{
Field subject = new Field("Subject", sqlDataReader["subject"].ToString());
fieldsDictionary.Add(subject.Name, subject);
Field description = new Field("Description", sqlDataReader["description"].ToString());
fieldsDictionary.Add(description.Name, description);
Field ticketID = new Field("TicketID", sqlDataReader["TicketID"].ToString());
fieldsDictionary.Add(ticketID.Name, ticketID);
Field author = new Field("Author", sqlDataReader["Author"].ToString());
fieldsDictionary.Add(author.Name, author);
}
sqlDataReader.Close();
//Second query
sqlCommand = new MySqlCommand(queryCustomFields.ToString(), sqlConnection);
sqlCommand.Parameters.AddWithValue("@TicketId", TicketID);
sqlDataReader = sqlCommand.ExecuteReader();
while (sqlDataReader.Read())
{
string fieldName = sqlDataReader["name"].ToString();
string fieldValue = sqlDataReader["value"].ToString();
string fieldFormat = sqlDataReader["field_format"].ToString();
if (fieldsDictionary.ContainsKey(fieldName))
{
fieldsDictionary[fieldName].Values.Add(fieldValue);
}
else
{
Field localField = new Field(fieldName, fieldValue, fieldFormat);
fieldsDictionary.Add(localField.Name, localField);
}
}
sqlDataReader.Close();
sqlConnection.Close();
return fieldsDictionary;
}
public Dictionary<int, string> GetARs()
{
Dictionary<int, string> ARDictionary = new Dictionary<int, string>();
MySqlConnection sqlConnection = new MySqlConnection(_databaseConfig);
StringBuilder sqlCommandIsAR = new StringBuilder();
sqlCommandIsAR.Append("SELECT issues.id AS TicketID, issues.tracker_id AS Tracker, issues.subject AS Subject, custom_values.custom_field_id, custom_values.value");
sqlCommandIsAR.Append(" FROM issues LEFT JOIN Custom_values ON custom_values.customized_id = issues.id ");
sqlCommandIsAR.Append(" WHERE tracker_id = @IsAR AND custom_field_id = @IsARNumber ");
sqlConnection.Open();
MySqlCommand commandGetARs = new MySqlCommand(sqlCommandIsAR.ToString(), sqlConnection);
commandGetARs.Parameters.AddWithValue("@IsAR", AR_TRACKER_ID);
commandGetARs.Parameters.AddWithValue("@IsARNumber", AR_NUMBER_ID);
MySqlDataReader sqlDataReader = null;
sqlDataReader = commandGetARs.ExecuteReader();
while (sqlDataReader.Read())
{
string DictionaryValue = sqlDataReader["TicketID"].ToString() + " - " + sqlDataReader["Subject"].ToString();
if (sqlDataReader["value"].ToString().Length != 0)
{
DictionaryValue += " [" + sqlDataReader["value"].ToString() + "]";
}
int key = int.Parse(sqlDataReader["TicketID"].ToString());
ARDictionary.Add(key, DictionaryValue);
}
sqlDataReader.Close();
sqlConnection.Close();
return ARDictionary;
}
#endregion
}
}
StringBuilder
prevents having to recreate a string each time you are adding to it. Using the String
class in C# means you are using an immutable object, but StringBuilder
is much faster in most cases since it's not having to create a new String each time you append to it.
So in general, if you are appending to a String many times, StringBuilder
will be more efficient than just doing str += "text to append"
(where str is a String
).
There are some caveats to be aware of here though, please refer to this answer.
A StringBuilder
allows you to build up a string without reallocating a buffer for the string's contents on every mutating operation (the same buffer is used throughout; it is only reallocated when the string expands beyond the current capacity). This makes the whole process of building up a big string much more performant.
In this case there is no dynamic building up of a string at all; the strings are practically hardcoded. Here StringBuilder
is totally pointless; it would actually be better for performance if the strings were hardcoded literals like this:
var queryDefaultFields = @"SELECT issues.id AS TicketID, issues.subject, issues.description,
CONCAT(users.firstname,' ', users.lastname) as Author
FROM issues LEFT JOIN users ON users.id =issues.author_id
WHERE issues.id = @TicketID";
My guess is that the author of this code either misused StringBuilder
because they remembered reading that "it's faster this way" but never really understood why, or else is guilty of negligent copy-pasting.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With