7

.NETで2つのDataTableの共通部分を取得する比較的簡単な方法はありますか?

明らかな方法を考えることができますが(O(n ^ 2)で両方のテーブルを繰り返し処理します)、利用できる場合はもう少しエレガントなものが必要です。私が見ていなかった知的な方法があるのではないかと思います。もちろん、読みやすさと保守性は重要なので、私はあまりにも「滑らか」なものには近づかないようにしています。

良いアイデアはありますか?

編集:ブライアンワッツは3.5に対してかなり優れたソリューションを持っているように見えますが、残念ながら私は.NET 2.0を使用しています(これについては言及する必要があります)。

4

4 に答える 4

14

.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);
    }
}
于 2009-01-27T21:28:08.553 に答える
3

役に立つと思われる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);
}
于 2009-01-27T21:30:23.463 に答える
1

protected void Page_Load(オブジェクト送信者, 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"]);
    }
}
于 2012-06-21T04:56:09.080 に答える
1

.NET 2.0 を使用しているため、Intersect メソッドの再実装を検討する必要があります。

この疑似コードは非常に役立つはずです。

于 2009-01-28T18:31:17.037 に答える