Is there a relatively straightforward way to get the intersection of two DataTables in .NET?
I can think of the obvious ways (iterating over both tables myself in O(n^2)), but I'd like something a little more elegant if it's available. I suspect there may be an intelligent way that I'm not seeing. Readability and maintainability are important, of course, so I'm trying to stay away from anything too "slick".
Any good ideas?
EDIT: It looks like Bryan Watts has a pretty great solution for 3.5, but unfortunately I'm in .NET 2.0 (which I should have mentioned.)
With .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);
}
}
Saw this example on MSDN which you may find useful. Its using the LINQ syntax.
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With