LINQ在DataTable上选择distinct不起作用

时间:2013-01-04 21:32:08

标签: c# vb.net linq datatable

我有以下数据 - 假设叫MyTable

Col1:    Col2:    Col3:    Col4:
1        abc      def      <null>
2        abc      def      ghi
1        abc      def      <null>
3        abc      def      <null>
1        abc      def      <null>

我正试图获得不同的行:

Col1:    Col2:    Col3:    Col4:
1        abc      def      <null>
2        abc      def      ghi
3        abc      def      <null>

我尝试了以下LINQ语句:

MyTable = (From dr As DataRow In MyTable Select dr).Distinct.CopyToDataTable

但它将原始数据表返回给我重复的行。

我做错了什么以及如何获得所需的输出?

4 个答案:

答案 0 :(得分:6)

Distinct依赖于所有实施IEquatable和/或合理实施GetHashCodeEquals的对象。 DataRow班级......没有。它没有检查Equals方法中每列的值是否相等,它只是使用默认实现,也就是说它检查引用是否相等,以及它是否相同。不是你想要的。

您可以提供自己的IEqualityComparer,因为您无法更改DataRow中的方法。

如果您向Distinct提供了一个实例,则以下内容应该有效:

public class DataRowComparer : IEqualityComparer<DataRow>
{
    public bool Equals(DataRow x, DataRow y)
    {
        for (int i = 0; i < x.Table.Columns.Count; i++)
        {
            if (!object.Equals(x[i], y[i]))
                return false;
        }
        return true;
    }

    public int GetHashCode(DataRow obj)
    {
        unchecked
        {
            int output = 23;
            for (int i = 0; i < obj.Table.Columns.Count; i++)
            {
                output += 19 * obj[i].GetHashCode();
            }
            return output;
        }
    }
}

答案 1 :(得分:2)

试试这个;

var distinctRows = (from DataRow dRow in MyTable.Rows
                    select new {col1=dRow["Col1"],col2=dRow["Col2"], col3=dRow["Col3"], col4=dRow["Col4"]}).Distinct();

foreach (var row in distinctRows) 
{
 //
}

答案 2 :(得分:1)

问题在于DataRow中的每个DataTable都是不同的对象。每个都是一个实例。

答案 3 :(得分:1)

尽管@ Servy的问题确实是这样做的正确方法 - 非常感谢Servy! 我还发现了另一种至少看起来更清洁的解决方案:

    MyTable = MyTable.DefaultView.ToTable(True)

这允许你只询问不同的记录,但是通过LINQ的原始请求否定 - 想想我将来为其他任何看过这个问题的人添加它。