我遇到的情况是需要在使用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();
提前感谢您的任何帮助!
答案 0 :(得分:3)
如果你坚持从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()));
答案 1 :(得分:3)
这是另一种方法,无需对前缀和后缀元素进行硬编码:
// 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));
}
测试代码:
var demoStringBuilder = new StringBuilder
("SELECT Apple,Carrot,Pear,Orange,Apple From fruit_table");
var cleanedBuilder = demoStringBuilder.DeduplicateColumns();
// Output: SELECT Apple,Carrot,Pear,Orange From fruit_table
这是一个小提琴:link