您需要解决两个问题:
- 如何将树结构转换为所有可能值集的集合。
- 如何将值集转换为 sql 表达式。
第一个问题可能最容易通过递归迭代列,并将一组值一起收集到列表中来解决:
// convert tree into collection of value sets
public IEnumerable<List<string>> ExplodeValueSets(T tree, int cIndex = 0) {
// recursive portion as long as there are more columns to process
if (cIndex < tree.column.Length) {
// recursive generate list for rest of columns
var subResult = ExplodeValueSets(tree, cIndex + 1);
// combine values in this column with recursively-generated
// sets from rest of columns to build up larger sets
foreach (var result in subResult)
foreach (var value in tree.column[cIndex].value)
yield return new List<string> { value.fieldVal }.Concat(result).ToList();
} else {
// base condition - all columns are processed, so return empty list
yield return new List<string>();
}
}
这会将图片中的原始树结构转换为列表集合:
从这里开始,将这些值集转换为 SQL 语句是一件简单的事情:
public string GenerateSQL(T tree) {
var valueSets = ExplodeValueSets(tree);
var sql = new StringBuilder();
foreach (var set in valueSets)
sql.AppendLine(GenerateSingleSQLInsert(tree, set));
var finalSql = sql.ToString();
return finalSql;
}
public string GenerateSingleSQLInsert(T tree, List<string> values) {
var sqlFormat = "insert into [{0}]([{1}]) values('{2}');";
var table = tree.tableName;
var columnList = string.Join("],[", tree.column.Select (c => c.className).ToArray());
var valueList = string.Join("','", values.ToArray());
var sql = string.Format(sqlFormat, table, columnList, valueList);
return sql;
}
使用您的示例树将所有内容组合在一起(我公开了所有属性和类以使其正常工作):
T tree = new T {
tableName = "T1",
column = new C[] {
new C { className = "C1", value = new V[] { new V { fieldVal = "V1" }, new V { fieldVal = "V2" } } },
new C { className = "C2", value = new V[] { new V { fieldVal = "V1" } } },
new C { className = "C3", value = new V[] { new V { fieldVal = "V1" } } }
}
};
var sql = GenerateSQL(tree);
Console.WriteLine(sql);
输出:
insert into [T1]([C1],[C2],[C3]) values('V1','V1','V1');
insert into [T1]([C1],[C2],[C3]) values('V2','V1','V1');