有效使用StringBuilder

时间:2010-02-22 06:47:09

标签: c# stringbuilder

我需要为数据表中的每一行附加一个Sqlquery。我有36列,并根据每列的数据类型我需要附加sqlquery。任何人都建议我这样做的有效方法。这是不好的方式编码使用“+”运算符在append?之间附加文本?

Following is my code.

 query ="INSERT INTO MASTERPI (tag,instrumenttag)");
 query += "VALUES ('" + createTagRow["tag"].ToString() + "','" + createTagRow["instrumenttag"].ToString() + "'");

谢谢, VIX

3 个答案:

答案 0 :(得分:5)

如果您已经使用StringBuilder,那么同时使用常规字符串连接是不利的。你否定了StringBuilder类的一半效用。不要这样做。使用StringBuilder.Append方法独占并删除那些+语句。

我也在想所有这些createTagRow(...).ToString()电话都是浪费。其中的一些东西正在将这些元素序列化为字符串,因此您可以有效地完成两次工作,创建字符串然后附加它。如果您可以将StringBuilder本身传递给那些createTagRow来电,那也会少得多......可怕。

实际上,在第二次查看时,似乎此代码正在构建SQL查询。 立即对该查询进行参数化。没有理由。这样,您甚至不必担心string.FormatStringBuilder相比连接,DB库将为您处理所有内容。

答案 1 :(得分:0)

如果您使用String.Format构建查询的每一行,您的代码可能会更具可读性,利用其占位符语法将行对象中的数据插入到查询文本中。

答案 2 :(得分:0)

如前所述,您应该考虑两种可能性:

  1. Aaronaught:Parameterize that query
  2. 如果您需要完全控制语句字符串,则应该查看.FormatWith extension并将不同的块重构为类,这样可以返回所需的部分。
  3. 一个小例子:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text.RegularExpressions;
    using System.Web.UI;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                var columns = new CommaSeparated();
    
                columns.Add("tag");
                columns.Add("instrumenttag");
                columns.Add("pointsource");
                columns.Add("pointtype");
                columns.Add("dataowner");
                columns.Add("dataaccess");
                columns.Add("location1");
                columns.Add("location2");
                columns.Add("location3");
                columns.Add("location4");
                columns.Add("location5");
                columns.Add("...");
    
    
                var values = new CommaSeparated();
    
                values.EncloseEachElementWith = "'";
                values.Add(createTagRow["tag"].ToString());
                values.Add(createTagRow["instrumenttag"].ToString());
                values.Add(createTagRow["pointsource"].ToString());
                values.Add(createTagRow["pointtype"].ToString());
                values.Add(createTagRow["dataowner"].ToString());
                values.Add(createTagRow["dataaccess"].ToString());
                values.Add(createTagRow["location1"].ToString());
                values.Add(createTagRow["location2"].ToString());
                values.Add(createTagRow["location3"].ToString());
                values.Add(createTagRow["location4"].ToString());
                values.Add(createTagRow["location5"].ToString());
                values.Add(createTagRow["..."].ToString());
    
                //INSERT INTO MASTERPI ({columns}) values ({values})
                var query = "INSERT INTO MASTERPI ({columns}) values ({values})".FormatWith(new { columns, values });
    
                Console.WriteLine(query);
                Console.ReadKey();
            }
        }
    
        public class CommaSeparated : List<string>
        {
            public CommaSeparated()
                : base()
            {
                EncloseEachElementWith = String.Empty;
            }
    
            public override string ToString()
            {
                var elements = this.Select(element => String.Format("{0}{1}{0}", EncloseEachElementWith, element));
    
                return String.Join(", ", elements.ToArray());
            }
    
            public string EncloseEachElementWith { get; set; }
        }
    
        public static class StringExtensions
        {
            public static string FormatWith(this string format, object source)
            {
                return FormatWith(format, null, source);
            }
    
            public static string FormatWith(this string format, IFormatProvider provider, object source)
            {
                if (format == null)
                    throw new ArgumentNullException("format");
    
                Regex r = new Regex(@"(?<start>\{)+(?<property>[\w\.\[\]]+)(?<format>:[^}]+)?(?<end>\})+",
                  RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
    
                List<object> values = new List<object>();
                string rewrittenFormat = r.Replace(format, delegate(Match m)
                {
                    Group startGroup = m.Groups["start"];
                    Group propertyGroup = m.Groups["property"];
                    Group formatGroup = m.Groups["format"];
                    Group endGroup = m.Groups["end"];
    
                    values.Add((propertyGroup.Value == "0")
                      ? source
                      : DataBinder.Eval(source, propertyGroup.Value));
    
                    return new string('{', startGroup.Captures.Count) + (values.Count - 1) + formatGroup.Value
                      + new string('}', endGroup.Captures.Count);
                });
    
                return string.Format(provider, rewrittenFormat, values.ToArray());
            }
        }
    }