DataTableに属するDataRowの任意の列から、重複する行を除去する方法はあるのですが、
DataTable dt = new DataTable(); DataColumn dc = new DataColumn("id", typeof(ulong)); dt.Columns.Add(dc); dc = new DataColumn("name", typeof(string)); dt.Columns.Add(dc); NewMethod(dt, 10000, "nakata"); NewMethod(dt, 10001, "honda"); NewMethod(dt, 10002, "kagawa"); NewMethod(dt, 10002, "nagatomo"); NewMethod(dt, 10003, "okazaki"); DataView dv = new DataView(dt); DataTable dt2 = dv.ToTable(true, "id");//trueでDistinct(重複を取り除く)
削除ではなく、同じ値のものを取得いたくて、その方法を調べたのですが、
たとえば、DataTable.Margeを使ってRowStatusで取得する方法
https://social.msdn.microsoft.com/Forums/ja-JP/3e46f64d-fed3-4370-a16a-0987c8710050/datatable-linq?forum=vbgeneralja
とか、なるほど!というのもあったのですが、これはprimary keyが設定してあるDataTable同志でなければいけないので、そうでない場合はどうすればいいか。というわけですが、DataTable.Selectで取り出してチェックするしかなさそう。
たとえば、こんな感じで。
DataTable dt = new DataTable(); DataColumn dc = new DataColumn("id", typeof(ulong)); dt.Columns.Add(dc); dc = new DataColumn("name", typeof(string)); dt.Columns.Add(dc); NewMethod(dt, 10000, "nakata"); NewMethod(dt, 10001, "honda"); NewMethod(dt, 10002, "kagawa"); NewMethod(dt, 10002, "nagatomo"); NewMethod(dt, 10003, "okazaki"); DataView dv = new DataView(dt); DataTable dt_distinct = dv.ToTable(true, "id");//重複除去 StringBuilder sb = new StringBuilder(); foreach (DataRow _dr in dt_distinct.Rows) { string id = _dr["id"].ToString(); if (id != "") { if ((int)dt.Compute("COUNT(id)", "id=" + id) > 1) { sb.Append(((sb.Length > 0) ? " OR " : "") + "id=" + id); } } } DataRow[] dr_array = dt.Select(sb.ToString()); DataTable dt_overlap = dr_array.CopyToDataTable();
なんか、気持ち悪いですが、Selectで重複しているIDだけを取り出すという、ベタなやり方。
こんなときは、LINQでいきます。
DataTable dt = new DataTable(); DataColumn dc = new DataColumn("id", typeof(ulong)); dt.Columns.Add(dc); dc = new DataColumn("name", typeof(string)); dt.Columns.Add(dc); NewMethod(dt, 10000, "nakata"); NewMethod(dt, 10001, "honda"); NewMethod(dt, 10002, "kagawa"); NewMethod(dt, 10002, "nagatomo"); NewMethod(dt, 10003, "okazaki"); var dr_array = from row in dt.AsEnumerable() where ( from _row in dt.AsEnumerable() where (ulong)row["id"] == (ulong)_row["id"] select _row["id"] ).Count() > 1 //重複していたら、2つ以上見つかる select row; DataTable dt_overlap = dr_array.CopyToDataTable();
もっと、すっきりできそうだけど、こんな感じで。