如何从对象列表构建动态字符串?

时间:2019-01-15 01:23:07

标签: c# list stringbuilder

让我们说我有一个名为Filter的类的列表

 public class Filter
    {
        [JsonProperty("field")]
        public string ColumnName { get; set; }
        [JsonProperty("value")]
        public string ColumnValue { get; set; }
        [JsonProperty("operator")]
        public object Operator {get; set;}
        public override string ToString()
        {
            return String.Format("{0} in ('{1}')", this.ColumnName, this.ColumnValue);
        }
     }

我需要一个列名称可以相同的过滤器列表。

因此,对于List中该类的每个实例,我可以有一个ColumnName“ LoanNumber”实例多次。每个LoanNumber将具有完全不同的值。因此,我需要收集所有值并将它们放在In子句字符串的单个LoanNumber下。

我如何遍历过滤器列表并构建一个看起来像这样的字符串

string where = "LoanNum in (1234,456, 55676) and Dates in (01/01/2019, 01/02/2019)";

到目前为止,我无法使所有数据看起来像上面的

 private string CreateWhereClause(List<Filter> filter)
        {
            StringBuilder sb = new StringBuilder();            
            foreach(var f in filter)
            {
                if (!sb.ToString().Contains(f.ColumnName))
                {
                    sb.Append(f.ToString() + " AND ");
                }else
                {
                    sb.Append(f.ToString() + " AND ");
                }
            }
            sb.Remove(sb.Length - 4, 4);
            return sb.ToString();
        }

上面的问题是我得到一个看起来像这样的字符串 LoanNum in (1234) and LoanNum in (3456) and Dates in (...) and Dates in (...)

2 个答案:

答案 0 :(得分:2)

我希望我能正确理解你。你可以做

var list = new List<Filter>
{
    new Filter{ColumnName="LoanNum",ColumnValue="1234"},
    new Filter{ColumnName="Dates",ColumnValue="01/01/2019"},
    new Filter{ColumnName="LoanNum",ColumnValue="456"},
    new Filter{ColumnName="Dates",ColumnValue="01/02/2019"},
    new Filter{ColumnName="LoanNum",ColumnValue="55676"},
};


var subResult = list
    .GroupBy(filter => filter.ColumnName)
    .Select(group => string.Format("{0} in ({1})", group.Key,
        string.Join(",", group.Select(filter => filter.ColumnValue))));

var where = string.Join(" and ", subResult);

输出

LoanNum in (1234,456,55676) and Dates in (01/01/2019,01/02/2019)

答案 1 :(得分:0)

我相信GroupBySelect是最好的选择,但是如果您想知道在刚开始做循环时如何做,一种方法是使用字典,其中KeyColumnName,而Value是关联的ColumnValue字符串的逗号分隔列表:

private static string CreateWhereClause(List<Filter> filters)
{
    if (filters == null) return null;
    if (!filters.Any()) return string.Empty;

    var results = new Dictionary<string, string>();

    foreach (var filter in filters)
    {
        if (results.ContainsKey(filter.ColumnName))
        {
            results[filter.ColumnName] += $",'{filter.ColumnValue}'";
        }
        else
        {
            results.Add(filter.ColumnName, $"'{filter.ColumnValue}'");
        }
    }

    return string.Join(" AND ", results.Select(result => 
        $"{result.Key} IN ({result.Value})"));
}

将其投入使用可能类似于:

private static void Main()
{
    var filters = new List<Filter>
    {
        new Filter {ColumnName = "LoanNum", ColumnValue = "1234"},
        new Filter {ColumnName = "Dates", ColumnValue = "01/01/2019"},
        new Filter {ColumnName = "LoanNum", ColumnValue = "456"},
        new Filter {ColumnName = "Dates", ColumnValue = "01/02/2019"},
        new Filter {ColumnName = "LoanNum", ColumnValue = "55676"},
    };

    var query = $"SELECT LOANS WHERE {CreateWhereClause(filters)}";

    Console.WriteLine(query);

    Console.ReadKey();
}

输出

enter image description here