在做項目的時候經常會遇到DataTable 里的數據重復,或者合並兩個DataTable后有數據重復
一般我們是想把重復的刪除掉,還有其它的方式實現比如用Linq和DataTable的DefaultView來去掉重復的行
做了一個小例子,很簡單的大家可以看一下,最后有完整的代碼
也可以直接下載工程:RemoveDupRowDemo.rar
先看一下效果
先寫一個數據源
DataTable _dt = new DataTable();
_dt.Columns.Add("id", typeof(int));
_dt.Columns.Add("name", typeof(string));
_dt.Columns.Add("address", typeof(string));
DataRow _dr = _dt.NewRow();
_dr["id"] = 1;
_dr["name"] = "lipeng";
_dr["address"] = "DongXiaoKou";
_dt.Rows.Add(_dr);
_dt.Rows.Add(_dr.ItemArray);
_dt.Rows.Add(_dr.ItemArray);
_dr = _dt.NewRow();
_dr["id"] = 2;
_dr["name"] = "xiaoNa";
_dr["address"] = "DongXiaoKou";
_dt.Rows.Add(_dr);
_dr = _dt.NewRow();
_dr["id"] = 3;
_dr["name"] = "BingLi";
_dr["address"] = "TianTongYuan";
_dt.Rows.Add(_dr);
_dt.Rows.Add(_dr.ItemArray);
Console.WriteLine("--------------------原來有重復數據的Table----------------------");
_dt.AsEnumerable().ToList().ForEach(
x =>
{
Console.WriteLine(x["id"].ToString() + " " + x["name"].ToString() + " " + x["address"].ToString());
});
Console.WriteLine();
先用Linq的Distinct方法實現,因為每行有好多列,要實現IEqualityComparer<T>接口
public class DataTableRowCompare : IEqualityComparer<DataRow> { #region IEqualityComparer<DataRow> 成員 public bool Equals(DataRow x, DataRow y) { return (x.Field<int>("id") == y.Field<int>("id")); } public int GetHashCode(DataRow obj) { return obj.ToString().GetHashCode(); } #endregion }
在Main里實現 吧
Console.WriteLine("--------------------用Linq去重復后的Table----------------------"); var _comPresult = _dt.AsEnumerable().Distinct(new DataTableRowCompare()); DataTable _resultDt = _comPresult.CopyToDataTable(); _resultDt.AsEnumerable().ToList().ForEach( x => { Console.WriteLine(x["id"].ToString() + " " + x["name"].ToString() + " " + x["address"].ToString()); }); Console.WriteLine();
用Table里的DefalutView實面DefalutView有個ToTable方法可以做到去重復
Console.WriteLine("--------------------用DefaultView去重復后的Table----------------------"); DataTable _dtDefalut = _dt.DefaultView.ToTable(true, "id", "name", "address"); _dtDefalut.AsEnumerable().ToList().ForEach( x => { Console.WriteLine(x["id"].ToString() + " " + x["name"].ToString() + " " + x["address"].ToString()); }); Console.ReadLine();
個人感覺 還是Linq的好一點,用DefaultView如果你的列少的話還好些,如果列太多的話工作量就太大了
下面給一下完整的代碼
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data; namespace RemoveDupRowDemo { class Program { static void Main(string[] args) { DataTable _dt = new DataTable(); _dt.Columns.Add("id", typeof(int)); _dt.Columns.Add("name", typeof(string)); _dt.Columns.Add("address", typeof(string)); DataRow _dr = _dt.NewRow(); _dr["id"] = 1; _dr["name"] = "lipeng"; _dr["address"] = "DongXiaoKou"; _dt.Rows.Add(_dr); _dt.Rows.Add(_dr.ItemArray); _dt.Rows.Add(_dr.ItemArray); _dr = _dt.NewRow(); _dr["id"] = 2; _dr["name"] = "xiaoNa"; _dr["address"] = "DongXiaoKou"; _dt.Rows.Add(_dr); _dr = _dt.NewRow(); _dr["id"] = 3; _dr["name"] = "BingLi"; _dr["address"] = "TianTongYuan"; _dt.Rows.Add(_dr); _dt.Rows.Add(_dr.ItemArray); Console.WriteLine("--------------------原來有重復數據的Table----------------------"); _dt.AsEnumerable().ToList().ForEach( x => { Console.WriteLine(x["id"].ToString() + " " + x["name"].ToString() + " " + x["address"].ToString()); }); Console.WriteLine(); Console.WriteLine("--------------------用Linq去重復后的Table----------------------"); var _comPresult = _dt.AsEnumerable().Distinct(new DataTableRowCompare()); DataTable _resultDt = _comPresult.CopyToDataTable(); _resultDt.AsEnumerable().ToList().ForEach( x => { Console.WriteLine(x["id"].ToString() + " " + x["name"].ToString() + " " + x["address"].ToString()); }); Console.WriteLine(); Console.WriteLine("--------------------用DefaultView去重復后的Table----------------------"); DataTable _dtDefalut = _dt.DefaultView.ToTable(true, "id", "name", "address"); _dtDefalut.AsEnumerable().ToList().ForEach( x => { Console.WriteLine(x["id"].ToString() + " " + x["name"].ToString() + " " + x["address"].ToString()); }); Console.ReadLine(); } } public class DataTableRowCompare : IEqualityComparer<DataRow> { #region IEqualityComparer<DataRow> 成員 public bool Equals(DataRow x, DataRow y) { return (x.Field<int>("id") == y.Field<int>("id")); } public int GetHashCode(DataRow obj) { return obj.ToString().GetHashCode(); } #endregion } }