是否有一种相对简单的方法可以在.NET中获取两个DataTable的交集?
我可以想到明显的方法(在O(n ^ 2)中自己迭代这两个表),但如果它可用,我想要更优雅的东西。我怀疑可能有一种我没有看到的聪明方式。当然,可读性和可维护性很重要,所以我试图远离任何太“光滑”的东西。
有什么好主意吗?
编辑:看起来Bryan Watts对3.5有一个非常好的解决方案,但不幸的是我在.NET 2.0中(我应该提到它。)
答案 0 :(得分:12)
使用.NET 3.5:
using System.Data;
public static class DataTableExtensions
{
public static IEnumerable<DataRow> Intersect(this DataTable table, DataTable other)
{
return table.AsEnumerable().Intersect(other.AsEnumerable());
}
public static IEnumerable<DataRow> Intersect(this DataTable table, DataTable other, IEqualityComparer<DataRow> comparer)
{
return table.AsEnumerable().Intersect(other.AsEnumerable(), comparer);
}
}
答案 1 :(得分:2)
在MSDN上看到这个例子你可能会觉得有用。它使用LINQ语法。
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
DataTable orders = ds.Tables["SalesOrderHeader"];
DataTable details = ds.Tables["SalesOrderDetail"];
var query =
from order in orders.AsEnumerable()
join detail in details.AsEnumerable()
on order.Field<int>("SalesOrderID") equals
detail.Field<int>("SalesOrderID")
where order.Field<bool>("OnlineOrderFlag") == true
&& order.Field<DateTime>("OrderDate").Month == 8
select new
{
SalesOrderID =
order.Field<int>("SalesOrderID"),
SalesOrderDetailID =
detail.Field<int>("SalesOrderDetailID"),
OrderDate =
order.Field<DateTime>("OrderDate"),
ProductID =
detail.Field<int>("ProductID")
};
foreach (var order in query)
{
Console.WriteLine("{0}\t{1}\t{2:d}\t{3}",
order.SalesOrderID,
order.SalesOrderDetailID,
order.OrderDate,
order.ProductID);
}
答案 2 :(得分:1)
由于您使用的是.NET 2.0,因此您应该考虑重新实现Intersect方法。
答案 3 :(得分:1)
protected void Page_Load(object sender,EventArgs e) {
DataTable dt1 = new DataTable();
dt1.Columns.Add("ColX", typeof(int));
DataTable dt2 = new DataTable();
dt2.Columns.Add("ColX", typeof(int));
for (int i = 1; i <= 5; i++)
{
DataRow row = dt1.NewRow();
row["ColX"] = 5 + i;
dt1.Rows.Add(row);
row = dt2.NewRow();
row["ColX"] = 9 + i;
dt2.Rows.Add(row);
}
intesect(dt1, dt2);
}
public void intesect(DataTable contacts1, DataTable contacts2)
{
var contacts = contacts1.AsEnumerable().Intersect(contacts2.AsEnumerable(), DataRowComparer.Default);
foreach (DataRow row in contacts)
{
Response.Write(row["ColX"]);
}
}