我坚持将一个巨大的if-chain转换成字典。在传统解决方案中,Excel导出如下所示:
foreach (DataRow dr in fullData.Rows)
{
DataRow newRow = dt.NewRow();
foreach (DataColumn dc in dt.Columns)
{
String s = dc.Caption;
if (s.Equals("ID"))
newRow[dc] = dr["id"];
else if (s.Equals("PQ-Nr"))
newRow[dc] = dr["pqNummer"];
else if (s.Equals("GJ"))
newRow[dc] = dr["geschaeftsjahr"];
else if (s.Equals("Link"))
newRow[dc] = dr["link"];
/*more complex example*/
else if(s.Equals("GF"))
{
string content = "";
int intVal = 0;
if (Int32.TryParse(dr["id"].ToString(), out intVal))
{
List<Freigabe> liste = DBHelper.getFreigabenByPersonalTyp(intVal, Personal.GF);
foreach (Freigabe f in liste)
{
//build content string here
}
}
newRow[dc] = content.TrimEnd();
}
/*plus around 60 more else if statements*/
}
dt.Rows.Add(newRow);
}
return dt;
我的想法是将规则和分配的实际行分成两部分。所以我创建了一个词典:
var rules = new Dictionary<Func<string, bool>, Func<DataRow, object>>()
{
{y => y == "ID", x => x["id"] },
{y => y == "PQ-Nr", x => x["pqNummer"] },
//....
};
为了获得当前列值,我执行以下操作:
foreach (DataRow dr in fullData.Rows)
{
DataRow newRow = dt.NewRow();
foreach (DataColumn dc in dt.Columns)
{
String s = dc.Caption;
newRow[dc] = from r in rules
where r.Key(s)
select r.Value(dr);
}
dt.Rows.Add(newRow);
}
return dt;
完成报告中每个单元格的内容现在为:System.Linq.Enumerable+WhereSelectEnumerableIterator
2 [System.Collections.Generic.KeyValuePair 2[System.Func
2 [System.String,System.Boolean],System.Func {{ 1}}而不是它的价值。
我在这里做错了什么?
答案 0 :(得分:5)
我建议更改rules
类型:
// No lambdas, just string to string
Dictionary<String, String> rules = new Dictionary<String, String>() {
{"ID", "id"},
{"PQ-Nr", "pqNumme"},
{"GJ", "geschaeftsjahr"},
{"Link", "link"},
//TODO: put other rules here
};
所以
foreach (DataRow dr in fullData.Rows) {
DataRow newRow = dt.NewRow();
foreach (DataColumn dc in dt.Columns)
newRow[dc] = dr[rules[dc.Caption]];
dt.Rows.Add(newRow);
}
修改:如果一些复杂规则(如编辑问题中的"GF"
一个)Dictionary<String, String> rule
也可以提供帮助:
foreach (DataColumn dc in dt.Columns) {
String rule;
if (rules.TryGetValue(dc.Caption, out rule))
newRow[dc] = dr[rule]; // <- all the simple rules
else if (dc.Caption.Equals("GF")) { // <- few specific rules
...
}
}
答案 1 :(得分:4)
rules.Where(r => r.Key(s)).
Select(r => r.Value(dr)).
FirstOrDefault(); // Should do the trick.