本文介绍了从两个数据表中查找公共列并将其用于 LINQ 中的连接条件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我有两个数据表,它们是完全动态的.这些将在运行时生成.现在我想通过查找公共列来连接这些表.
I have two Data Tables and these are completely dynamic. These would be generated at runtime. Now I want to Join these tables by finding the common columns.
请查看以下代码以获取更多信息
Kindly check below code for further information
public DataTable DataTableJoiner(DataTable dt1, DataTable dt2)
{
using (DataTable targetTable = dt1.Clone())
{
var dt2Query = dt2.Columns.OfType<DataColumn>().Select(dc =>
new DataColumn(dc.ColumnName, dc.DataType, dc.Expression, dc.ColumnMapping));
var dt2FilterQuery = from dc in dt2Query.AsEnumerable()
where targetTable.Columns.Contains(dc.ColumnName) == false
select dc;
targetTable.Columns.AddRange(dt2FilterQuery.ToArray());
var rowData=from row1 in dt1.AsEnumerable()
join row2 in dt2.AsEnumerable()
on row1.Field<int>("ID") equals row2.Field<int>("ID")
select row1.ItemArray.Concat(row2.ItemArray.Where(r2 => row1.ItemArray.Contains(r2) == false)).ToArray();
foreach (object[] values in rowData) targetTable.Rows.Add(values);
return targetTable;
}
}
在上面我将ID"硬编码为公共列.我需要动态生成/识别公共列.请帮帮我.
In the above I have hardcoded "ID" as the common column. I need the common column to be produced/recognized dynamically. Please help me.
推荐答案
这个对我有用的怎么样:
What about this, which worked for me:
private DataTable DataTableJoiner(DataTable dt1, DataTable dt2)
{
var commonColumns = dt1.Columns.OfType<DataColumn>().Intersect(dt2.Columns.OfType<DataColumn>(), new DataColumnComparer());
var result = new DataTable();
result.Columns.AddRange(
dt1.Columns.OfType<DataColumn>()
.Union(dt2.Columns.OfType<DataColumn>(), new DataColumnComparer())
.Select(c => new DataColumn(c.Caption, c.DataType, c.Expression, c.ColumnMapping))
.ToArray());
var rowData = dt1.AsEnumerable().Join(
dt2.AsEnumerable(),
row => commonColumns.Select(col => row[col.Caption]).ToArray(),
row => commonColumns.Select(col => row[col.Caption]).ToArray(),
(row1, row2) =>
{
var row = result.NewRow();
row.ItemArray = result.Columns.OfType<DataColumn>().Select(col => row1.Table.Columns.Contains(col.Caption) ? row1[col.Caption] : row2[col.Caption]).ToArray();
return row;
},
new ObjectArrayComparer());
foreach (var row in rowData)
result.Rows.Add(row);
return result;
}
为此,您需要另外声明这两个类:
For this to work, you need to declare these 2 classes in addition:
private class DataColumnComparer : IEqualityComparer<DataColumn>
{
#region IEqualityComparer<DataColumn> Members
public bool Equals(DataColumn x, DataColumn y)
{
return x.Caption == y.Caption;
}
public int GetHashCode(DataColumn obj)
{
return obj.Caption.GetHashCode();
}
#endregion
}
private class ObjectArrayComparer : IEqualityComparer<object[]>
{
#region IEqualityComparer<object[]> Members
public bool Equals(object[] x, object[] y)
{
for (var i = 0; i < x.Length; i++)
{
if (!object.Equals(x[i], y[i]))
return false;
}
return true;
}
public int GetHashCode(object[] obj)
{
return obj.Sum(item => item.GetHashCode());
}
#endregion
}
我希望这会有所帮助!
这篇关于从两个数据表中查找公共列并将其用于 LINQ 中的连接条件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!