3

我有以下数据表 - 假设被称为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

4 回答 4

6

Distinct依赖于所有实现IEquatable和/或具有和的合理实现的GetHashCode对象EqualsDataRow班级……没有。它不检查Equals方法中每一列的值是否相等,它只是使用默认实现,也就是说它检查引用是否相等,这不是你想要的。

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

如果您将其实例提供给 to ,则以下内容应该有效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;
        }
    }
}
于 2013-01-04T21:35:14.857 回答
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) 
{
 //
}
于 2013-01-04T21:37:06.630 回答
1

问题是DataRowDataTable的每一个都是不同的对象。每一个都是一个实例。

于 2013-01-04T21:36:19.300 回答
1

尽管@Servy 的问题确实是正确的方法 - 非常感谢 Servy!我还找到了另一个至少看起来更干净的解决方案:

    MyTable = MyTable.DefaultView.ToTable(True)

这允许您只要求不同的记录,但通过 LINQ 执行它的原始请求否定 - 想我会为将来查看此问题的其他人添加它。

于 2013-01-04T22:01:57.520 回答