C# 在C中重复StringBuilder项列表

C# 在C中重复StringBuilder项列表,c#,linq,C#,Linq,在这种情况下,我需要重复使用StringBuilder生成的SQL select语句中的列列表。我还需要返回一个StringBuilder对象 我想出的解决办法很管用,但看起来像一场该死的噩梦。有人能提出一个更干净的方法来实现这一点吗 //The SQL statement is being passed to my code as a StringBuilder //This is just scaffolding to fake that input. StringBuilder items

在这种情况下,我需要重复使用StringBuilder生成的SQL select语句中的列列表。我还需要返回一个StringBuilder对象

我想出的解决办法很管用,但看起来像一场该死的噩梦。有人能提出一个更干净的方法来实现这一点吗

//The SQL statement is being passed to my code as a StringBuilder
//This is just scaffolding to fake that input.
StringBuilder items = new StringBuilder();
items.Append("SELECT ");
items.Append("Apple,");
items.Append("Carrot,");
items.Append("Pear,");
items.Append("Orange,");
items.Append("Apple");
items.Append(" From fruit_table");
//End scaffolding

//My code start:
//Chop off the non-important parts
items.Replace("SELECT ", "");
items.Replace(" From fruit_table", "");

//Convert string to list, seperating on commas
List<string> itemList = items.ToString().ToUpper().Split(',').ToList<string>();

//Found a handy "distinct" method in LINQ library
itemList = itemList.Distinct().ToList();

//Wipe out the original stringbuilder. For clarity and consistency with some other code, I'd like to reuse the same stringBuilder that was passed to me.
items.Clear();

//Rebuild my stringbuilder, now deduped
items.Append("SELECT ");
itemList.ForEach(x => items.Append(x + ","));
//Remove that comma after last fruit item
items.Remove((items.Length - 1), 1);
items.Append(" FROM fruit_table");

//Not really going to output to console, but you
//get the idea.
Console.WriteLine(items.ToString());
Console.ReadLine();

提前感谢您的帮助

如果您一直坚持从StringBuilder开始,那么我认为您已经基本确定了需要做什么

不过,我会让它更干净一点,就像这样:

var prefix = "SELECT ";
var suffix = " From fruit_table";
var result =
    String.Format("{0}{2}{1}",
        prefix,
        suffix,
        String.Join(",",
            items
                .ToString()
                .Replace(prefix, "")
                .Replace(suffix, "")
                .Split(',')
                .Select(x => x.Trim())
                .Distinct()));
items.Clear();
items.Append(result);
之前:

SELECT Apple,Carrot,Pear,Orange,Apple From fruit_table
之后:

SELECT Apple,Carrot,Pear,Orange From fruit_table
如果您知道列的名称之间没有空格,那么这会稍微干净一些:

var result =
    String.Format("{0}{2}{1}",
        prefix,
        suffix,
        String.Join(",",
            items
                .ToString()
                .Split(' ')[1]
                .Split(',')
                .Distinct()));

如果您一直坚持从StringBuilder开始,那么我认为您已经大致了解了需要做什么

不过,我会让它更干净一点,就像这样:

var prefix = "SELECT ";
var suffix = " From fruit_table";
var result =
    String.Format("{0}{2}{1}",
        prefix,
        suffix,
        String.Join(",",
            items
                .ToString()
                .Replace(prefix, "")
                .Replace(suffix, "")
                .Split(',')
                .Select(x => x.Trim())
                .Distinct()));
items.Clear();
items.Append(result);
之前:

SELECT Apple,Carrot,Pear,Orange,Apple From fruit_table
之后:

SELECT Apple,Carrot,Pear,Orange From fruit_table
如果您知道列的名称之间没有空格,那么这会稍微干净一些:

var result =
    String.Format("{0}{2}{1}",
        prefix,
        suffix,
        String.Join(",",
            items
                .ToString()
                .Split(' ')[1]
                .Split(',')
                .Distinct()));

下面是另一种不必硬编码前缀和后缀元素的方法:

// Encapsulate the behavior in an extension method we can run
// directly on a StringBuilder object
public static StringBuilder DeduplicateColumns(this StringBuilder input) {
    // Assume that we can split into large "chunks" on spaces
    var sections = input.ToString().Split(' ');
    var resultSections = new List<string>();

    foreach (var section in sections) {
        var items = section.Split(',');

        // If there aren't any commas, spit this chunk back out
        // Otherwise, split on the commas and get distinct items
        if (items.Count() == 1)
            resultSections.Add(section);
        else
            resultSections.Add(string.Join(",", items.Distinct()));
    }

    return new StringBuilder(string.Join(" ", resultSections));
}

这里有一个小问题:

这里有另一种不用硬编码前缀和后缀元素的方法:

// Encapsulate the behavior in an extension method we can run
// directly on a StringBuilder object
public static StringBuilder DeduplicateColumns(this StringBuilder input) {
    // Assume that we can split into large "chunks" on spaces
    var sections = input.ToString().Split(' ');
    var resultSections = new List<string>();

    foreach (var section in sections) {
        var items = section.Split(',');

        // If there aren't any commas, spit this chunk back out
        // Otherwise, split on the commas and get distinct items
        if (items.Count() == 1)
            resultSections.Add(section);
        else
            resultSections.Add(string.Join(",", items.Distinct()));
    }

    return new StringBuilder(string.Join(" ", resultSections));
}

这里有一个小问题:

只是为了确定,把它扔掉-没有办法更改代码的输入?我知道你的意思,但不,不是真的。如果我上面的代码工作正常,无论如何都不应该有重复的代码。我只需要暂时插入我的重复数据消除代码,直到下一个主要版本中修复了较大的部分。只是扔掉它以确保-没有办法更改代码的输入?我知道你的意思,但不,不是真的。如果我上面的代码工作正常,无论如何都不应该有重复的代码。我只需要暂时插入我的重复数据消除代码,直到下一个主要版本中修复较大的部分。谢谢Nate,我喜欢这个。谢谢Nate,我喜欢这个。