我有以下数据 - 假设叫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
但它将原始数据表返回给我重复的行。
我做错了什么以及如何获得所需的输出?
答案 0 :(得分:6)
Distinct
依赖于所有实施IEquatable
和/或合理实施GetHashCode
和Equals
的对象。 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的原始请求否定 - 想想我将来为其他任何看过这个问题的人添加它。