C# 根据指定的列删除DataTable中重复的数据行,保保留其中一条重复的数据,求Linq写法

高彬 2015-07-27 06:28:10

最近开发中遇到需要删除DataTable中重复项的需求,手写了一个方法,见下方代码 ,不过总觉得不够好,尝试用Linq写,但是尝试了很多次,都没有写 来,请Linq的写法!!!

源表如下:
姓名 年龄 备注
--------------------
1 2 3
1 3 2
1 2 4


希望根据“姓名 和 年龄”删除重复项,期望结果如下(因为源表第1行与第3行重复):
姓名 年龄 备注
--------------------
1 2 3
1 3 2



/// <summary>
/// 按照fieldName从sourceTable中选择出不重复的行,
/// 并且返回sourceTable中所有的列。
/// </summary>
/// 2015-07-27 gaobin
/// <param name="tableName">表名</param>
/// <param name="sourceTable">源表</param>
/// <param name="fieldName">字段</param>
/// <returns>一个新的不含重复行的DataTable</returns>
public static DataTable DistinctSomeColumn(DataTable sourceTable, params string[] fieldName)
{
DataTable dt2 = sourceTable.Clone();
DataView v1 = dt2.DefaultView;
StringBuilder filter = new StringBuilder();
foreach (DataRow row in sourceTable.Rows)
{
for (int i = 0; i < fieldName.Length; i++)
{
filter.AppendFormat("{0}='{1}'", fieldName[i], row[fieldName[i]].ToString().TrimEnd());
if (i < fieldName.Length - 1)
{
filter.Append(" and ");
}
}

v1.RowFilter = filter.ToString();

if (v1.Count > 0)
{
filter = new StringBuilder();
continue;
}
dt2.Rows.Add(row.ItemArray);
filter = new StringBuilder();
}
return dt2;
}
...全文
966 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
ajianchina 2015-07-28
  • 打赏
  • 举报
回复
想到了一个更好的方法,不等明天了,用这个,呵呵。

public static DataTable DistinctSomeColumn(DataTable sourceTable, params string[] fieldName)
{
    if (fieldName == null || fieldName.Length == 0) return sourceTable;
    return sourceTable.AsEnumerable().Distinct(new ColumnEquals(fieldName)).CopyToDataTable();
}

public class ColumnEquals : IEqualityComparer<DataRow>
{
    public ColumnEquals(string[] sArr)
    {
        _sArr = sArr;
    }

    private string[] _sArr;
    public bool Equals(DataRow x, DataRow y)
    {
        return !_sArr.Any(p => !x[p].Equals(y[p]));
    }

    public int GetHashCode(DataRow obj)
    {
        return obj.ToString().GetHashCode();
    }
}
高彬 2015-07-28
  • 打赏
  • 举报
回复
重写表达式!思路真好!!!
ajianchina 2015-07-27
  • 打赏
  • 举报
回复

public static DataTable DistinctSomeColumn(DataTable sourceTable, params string[] fieldName)
{
    return sourceTable.AsEnumerable().GroupBy(row =>
            {
                StringBuilder s = new StringBuilder();
                fieldName.ToList().ForEach(p => s.Append(row[p].ToString()));
                return s.ToString();
            }).Select(p => p.First()).CopyToDataTable<DataRow>();
}
高彬 2015-07-27
  • 打赏
  • 举报
回复
由于项目有多人开发,所以要封装成公用的方法,供其他开发人员使用。
高彬 2015-07-27
  • 打赏
  • 举报
回复
回复2楼: 刚才我试了一下,直接运行您给的那个语句是可以的,不好意思,我没有把问题完全表达出来 ,还有一个需求是 要过滤重复项的字段是不定的,如下面的方法应该如何完善??

public static DataTable DistinctSomeColumn(DataTable sourceTable, params string[] fieldName)
{
      //这里应该怎么写代码,才能根据fieldName 中的字段来过滤重复项?
}
{
ajianchina 2015-07-27
  • 打赏
  • 举报
回复
老表、新表名字倒了,知道就行了
ajianchina 2015-07-27
  • 打赏
  • 举报
回复
先上一个二重分组的,没试,你先试试看。

DataTable 老表= 新表.AsEnumerable().GroupBy(p => p["姓名"]).SelectMany(p => p.GroupBy(s => s["年龄"]).Select(x => x.First())).CopyToDataTable<DataRow>();
也可以
高彬 2015-07-27
  • 打赏
  • 举报
回复
不好意思,注释不是最新的!代码肯定是没有问题的,我已经测试过了,并且在使用了。就是觉得这种写法不够好,想用Linq实现 ,高手请简单写下代码 !!!!!

110,535

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧