次を使用すると、繰り返し行が表示されます。
DataTable dt = list.AsEnumerable().Distinct().CopyToDataTable();
なぜDistinct()
機能しないのですか?
私のデータテーブル構造:
serial,doc_content,doc_name,selected
int ,Byte[] ,string ,int
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 文字列に変換していることに注意してください。これは最も効率的なアプローチではありませんが、簡単です:) コンテンツが必要ない場合は、その部分のプロジェクションを取り除くことができます。
Distinct
行に格納されている値を考慮に入れるためのデフォルトとメソッドをDataRow
オーバーライドしないため、オブジェクト参照を比較します。Equals
GetHashCode
object
独自の等値比較子を指定できるEnumerable.Distinctのオーバーロードがあり、必要なインターフェイスを実装するDataRowComparerクラスがあります。IEqualityComparer<DataRow>
その後、次のように使用できます。
var distinct = list.AsEnumerable()
.Distinct(DataRowComparer.Default)
.CopyToDataTable();