3

私はDataTable次のようなものを持っています:

 ID   Name    DateBirth
.......................
 1     aa      1.1.11
 2     bb      2.3.11
 2     cc      1.2.12
 3     cd      2.3.12

同じ ID を持つ行を削除して、次のようなものを取得する最速の方法は次のとおりです (最初の行を保持し、次の行を削除します)。

 ID   Name    DateBirth
.......................
 1     aa      1.1.11
 2     bb      2.3.11
 3     cd      2.3.12

行番号が大きいため、テーブル行を二重に渡したくありません。可能であればLinQを使用したいのですが、大きなクエリになると思いますので、比較子を使用する必要があります。

4

6 に答える 6

10

LINQ to DataTable を使用して、列に基づいて区別し、この列でグループ化してから、最初に選択するIDことができます。

  var result = dt.AsEnumerable()
                 .GroupBy(r => r.Field<int>("ID"))
                 .Select(g => g.First())
                 .CopyToDataTable();
于 2013-03-27T16:11:22.630 に答える
3

私は同じ状況を解決していて、非常に興味深いと感じたので、私の発見を共有したいと思います.

  1. 行がALL COLUMNSに基づいて区別される場合。
DataTable newDatatable = dt.DefaultView.ToTable(true, "ID", "Name", "DateBirth");

ここで言及した列は、それらのみが に返されnewDatatableます。

  1. 1 つの列に基づいて区別され、列の型がintである場合は、クエリを優先しLINQます。
  DataTable newDatatable = dt.AsEnumerable()
                           .GroupBy(dr => dr.Field<int>("ID"))
                           .Select(dg => dg).Take(1)
                           .CopyToDataTable();
  1. 1 つの列に基づいて区別され、列の型が文字列である場合は、ループを優先します。
List<string> toExclude = new List<string>();
for (int i = 0; i < dt.Rows.Count; i++)
{
    var idValue = (string)dt.Rows[i]["ID"];
    if (toExclude.Contains(idValue))
    {
        dt.Rows.Remove(dt.Rows[i]);
        i--;
    }
    toExclude.Add(glAccount);
}

3番目は私のお気に入りです。

質問で尋ねられていないことをいくつか答えたかもしれません。それは善意で行われ、興奮もほとんどありませんでした.

それが役に立てば幸い。

于 2014-06-24T13:28:41.850 に答える
2
  1. それぞれのレコード数を取得するID
var rowsToDelete = 
    (from row in dataTable.AsEnumerable()
    group row by row.ID into g
    where g.Count() > 1
  1. 保持するレコードを決定し (基準がわかりません。DoB で並べ替えNameて最初のレコードを保持します)、残りを選択します。
select g.OrderBy( dr => dr.Field<DateTime>( "DateBirth" ) ).ThenBy( dr => dr.Field<string>( "Name" ) ).Skip(1))
  1. 平らにする
.SelectMany( g => g );
  1. 行を削除する
rowsToDelete.ForEach( dr => dr.Delete() );
  1. 変更を受け入れる
dataTable.AcceptChanges();
于 2013-03-27T16:37:03.923 に答える
2

あなたはこれを試すことができます

DataTable uniqueCols = dt.DefaultView.ToTable(true, "ID");
于 2013-03-27T16:10:24.643 に答える
2

必ずしも最も効率的なアプローチではありませんが、おそらく最も読みやすいアプローチです。

table = table.AsEnumerable()
    .GroupBy(row => row.Field<int>("ID"))
    .Select(rowGroup => rowGroup.First())
    .CopyToDataTable();

Linq もより強力です。たとえば、ロジックを変更し、各 id-group の最初の (任意の) 行を選択するのではなく、次のように最後の行を選択する場合DateBirth:

table = table.AsEnumerable()
    .GroupBy(row => row.Field<int>("ID"))
    .Select(rowGroup => rowGroup
                          .OrderByDescending(r => r.Field<DateTime>("DateBirth"))
                          .First())
    .CopyToDataTable();
于 2013-03-27T16:12:50.650 に答える