-1

次を使用すると、繰り返し行が表示されます。

 DataTable dt = list.AsEnumerable().Distinct().CopyToDataTable();  

なぜDistinct()機能しないのですか?


私のデータテーブル構造:

serial,doc_content,doc_name,selected
int   ,Byte[]     ,string  ,int
4

2 に答える 2

2

Distinct()一連のデータ行を呼び出しています。DataRow私はoverridesを信じていないEqualsので、どの 2 つのDataRowオブジェクトも等しくないと比較されます。

IEqualityComparer<DataRow>最初にto を渡すか、Distinct()別の型 (たとえば、等価比較を既に実装している匿名型) に射影Distinct()し、新しいシーケンスを呼び出す必要があります。

で作業を続けたい場合はDataRow、等値比較子を実装するのがおそらく最も簡単です。有望に見えますが(以前は知りませんでした)フィールドが原因で特定のケースでは機能しない場合があります。DataRowComparer.Default byte[]

個人的には、できるだけ早くデータをより具体的な型に変換するのが好きですが、YMMV. DataTable全体をより具体的な型に投影する場合は、代わりにそのSelect部分をWhere句として記述できることに注意してください。

var list = table.AsEnumerable()
     .Select(row => new { Serial = row.Field<string>("serial"),
                          ContentBase64 = Convert.ToBase64String(row.Field<byte>("doc_content")),
                          Name = row.Field<string>("doc_name"),
                          Selected = row.Field<int>("selected") })
     .Where(x => x.Selected == 1)
     .Distinct()
     .ToList();

等価比較が簡単に機能するように、コンテンツを base64 文字列に変換していることに注意してください。これは最も効率的なアプローチではありません、簡単です:) コンテンツが必要ない場合は、その部分のプロジェクションを取り除くことができます。

于 2013-02-23T12:36:38.060 に答える
2

Distinct行に格納されている値を考慮に入れるためのデフォルトとメソッドをDataRowオーバーライドしないため、オブジェクト参照を比較します。EqualsGetHashCodeobject

独自の等値比較子を指定できるEnumerable.Distinctのオーバーロードがあり、必要なインターフェイスを実装するDataRowComparerクラスがあります。IEqualityComparer<DataRow>

その後、次のように使用できます。

var distinct = list.AsEnumerable()
    .Distinct(DataRowComparer.Default)
    .CopyToDataTable();
于 2013-02-23T12:38:19.790 に答える