4

私はC++といくつかのC#のみを実行しましたが、MySQLは初めてであり、ここで文字列ビルダーの目的を理解していません。

このコードは、Webページからデータを抽出し、ブックマークを使用して既存のWordファイルに挿入するために使用されるプログラムの一部です。

マイコード

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
    }
}
4

4 に答える 4

6

StringBuilder追加するたびに文字列を再作成する必要がなくなります。C# でクラスを使用Stringするということは、不変オブジェクトを使用していることを意味しますが、StringBuilder追加するたびに新しい String を作成する必要がないため、ほとんどの場合ははるかに高速です。

したがって、一般に、文字列に何度も追加する場合はStringBuilder、単に行うよりも効率的ですstr += "text to append"(ここで str は ですString)。

ここで注意すべき点がいくつかありますが、この回答を参照してください。

于 2012-09-20T12:42:02.170 に答える
5

一般に

AStringBuilderを使用すると、変更操作のたびに文字列の内容用のバッファーを再割り当てすることなく、文字列を作成できます (同じバッファーが使用されます。文字列が現在の容量を超えて拡張された場合にのみ再割り当てされます)。これにより、大きな文字列を構築するプロセス全体のパフォーマンスが大幅に向上します。

このコードでは

この場合、文字列の動的な構築はまったくありません。文字列は実質的にハードコードされています。ここでStringBuilderはまったく無意味です。文字列が次のようにハードコードされたリテラルである場合、実際にはパフォーマンスが向上します。

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";

私の推測では、このコードの作成者は、StringBuilder「この方法の方が速い」と読んだことを覚えていたが、その理由を本当に理解していなかったため、誤用したか、または怠慢なコピーペーストの罪を犯したと考えられます。

于 2012-09-20T12:45:54.767 に答える
4

文字列をたくさん追加するので、パフォーマンスを向上させるため。参照型であっても型のstringように振る舞うことはよく知られていますvalue

したがって、文字列を追加するたびに、新しい文字列オブジェクトが割り当てられます。

string s = "hello"; 
s += " world"; //NEW STRING OBJECT ALLOCATED 

の場合StringBuilder、代わりに、新しい割り当てはありませんが、最後に追加するだけです。

StringBuilder queryDefaultFields = new StringBuilder();
queryDefaultFields.Append("hello");   //THE SAME queryDefaultFields OBJECT
queryDefaultFields.Append(" world");  //THE SAME queryDefaultFields OBJECT
于 2012-09-20T12:42:55.170 に答える
0

StringBuilderは変更可能であるため(文字列とは逆に)、参照がある限り、いつでもAppend(またはAppendLine)メソッドを使用してデータを追加することができます。

于 2012-09-20T12:43:45.887 に答える