-1

使用以下内容时,我得到重复的行:

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

为什么Distinct()不起作用?


我的数据表结构:

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

2 回答 2

2

您正在调用Distinct()一系列数据行。我不相信DataRowoverrides 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 字符串,以便平等比较可以简单地工作。这不是最有效的方法,但很容易:) 如果您不需要内容,您可以摆脱那部分投影。

于 2013-02-23T12:36:38.060 回答
2

Distinct将比较对象引用,因为DataRow不会覆盖默认值EqualsGetHashCode方法 fromobject以考虑存储在行中的值。

有一个Enumerable.Distinct的重载,它允许您指定自己的相等比较器,并且有一个DataRowComparer类实现所需的IEqualityComparer<DataRow>接口。

然后你可以像这样使用它:

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