使用以下内容时,我得到重复的行:
DataTable dt = list.AsEnumerable().Distinct().CopyToDataTable();
为什么Distinct()
不起作用?
我的数据表结构:
serial,doc_content,doc_name,selected
int ,Byte[] ,string ,int
您正在调用Distinct()
一系列数据行。我不相信DataRow
overrides Equals
,所以任何两个DataRow
对象都会比较为不相等。
您需要先将IEqualityComparer<DataRow>
toDistinct()
或 project 传递给另一种类型(例如,匿名类型,它已经实现了相等比较)并调用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
方法 fromobject
以考虑存储在行中的值。
有一个Enumerable.Distinct的重载,它允许您指定自己的相等比较器,并且有一个DataRowComparer类实现所需的IEqualityComparer<DataRow>
接口。
然后你可以像这样使用它:
var distinct = list.AsEnumerable()
.Distinct(DataRowComparer.Default)
.CopyToDataTable();