Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding the intersection of two .NET DataTables

Tags:

.net

datatable

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.)

like image 851
Beska Avatar asked Jan 27 '09 21:01

Beska


2 Answers

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);
    }
}
like image 195
Bryan Watts Avatar answered Sep 20 '22 13:09

Bryan Watts


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);
}
like image 23
Perpetualcoder Avatar answered Sep 22 '22 13:09

Perpetualcoder