我加入了两个IEnumerable<DataRow>
report1
和report2
var query = report1
.Join(report2,
row1 => row1.Field<string>("ReportID"),
row2 => row2.Field<string>("ReportID"),
(row1, row2) => new
{
ReportID = row1.Field<string>("ReportID"),
CustomerName = row1.Field<string>("CustomerName"),
CustomerSpending = row2.Field<string>("CustomerSpending")
});
现在假设我有两个List<string>
fieldsReport1
和fieldsReport2
每个列表包含每个报告中的字段名称,以使其进入最终加入。如何修改上述查询以在结果选择器中包含列表?
答案 0 :(得分:1)
如果我理解正确,你需要这样的东西:
var report1 = new List<DataRow>();
var report2 = new List<DataRow>();
var report1Fields = new List<string> { "ReportId", "CustomerName" };
var report2Fields = new List<string> { "CustomerSpending" };
var query = report1
.Join(report2,
row1 => row1.Field<string>("ReportID"),
row2 => row2.Field<string>("ReportID"),
(row1, row2) => new
{
Report1Data = report1Fields.Select(x => row1.Field<string>(x)).ToList(),
Report2Data = report2Fields.Select(x => row2.Field<string>(x)).ToList(),
});
答案 1 :(得分:1)
使用动态字段创建匿名对象没有简单的方法,但是为此设计了另一个类:System.Dynamic.ExpandoObject
。 ExpandoObject
支持IDictionary<string,object>
接口,允许您动态添加新属性。
使用扩展方法一次添加多个属性并将其链接起来,您可以执行以下操作:
var query = report1
.Join(report2,
row1 => row1.Field<string>("ReportID"),
row2 => row2.Field<string>("ReportID"),
(row1, row2) => (new ExpandoObject() as IDictionary<string,object>).AddRange(fieldsReport1, f => f, f => row1[f]).AddRange(fieldsReport2, f => f, f => row2[f])
);
顺便说一句,您将如何使用/提取这些属性取决于您。在某些时候,直接使用Dictionary<string,object>
可能更有意义。
这是扩展方法:
public static IDictionary<TKey, TValue> AddRange<TSrc, TKey, TValue>(this IDictionary<TKey, TValue> dictObj, IEnumerable<TSrc> srcFields, Func<TSrc, TKey> keySelector, Func<TSrc, TValue> valueSelector) {
foreach (var kvp in srcFields)
if (!dictObj.ContainsKey(keySelector(kvp)))
dictObj.Add(keySelector(kvp), valueSelector(kvp));
return dictObj;
}
请注意,如果两个字段名称列表存在冲突,则第一个表会获胜。您可以修改扩展方法以获取密钥冲突解决方案lambda,然后根据需要修复冲突的字段名称。
作为替代方案,您可以创建Dictionary
,然后将结果转换为DataTable
:
public static DataTable AsDataTable(this IEnumerable<IDictionary<string, object>> rows) {
var dt = new DataTable();
if (rows.Any()) {
foreach (var kv in rows.First())
dt.Columns.Add(kv.Key, kv.Value.GetType());
foreach (var r in rows)
dt.Rows.Add(r.Values.ToArray());
}
return dt;
}