DataRow按指定的ColumnName列表进行比较,用于Linq Distinct计算
测试用例
[TestMethod]
public void TestMethod1()
{
System.Data.DataTable dataTable = new System.Data.DataTable();
dataTable.Columns.Add("x");
dataTable.Columns.Add("y");
dataTable.Columns.Add("z");
dataTable.Rows.Add("1", "2", "3");
dataTable.Rows.Add("1", "2", "2");
dataTable.Rows.Add("1", "3", "3");
var dd = new B2B_Function.DataRowEqualityComparer("x", "y");
var dd1= dataTable.AsEnumerable().Distinct(dd);
}
实现代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
using System.Data;
namespace B2B_Function
{
/// <summary>
/// <para>DataRow相等比较类,可以自动KEY Column</para>
/// <para>只抓取指定的Column</para>
/// </summary>
public class DataRowEqualityComparer : IEqualityComparer<DataRow>
{
string[] ColumnNames;
/// <summary>
/// 初始化
/// </summary>
/// <param name="ColumnNames">ColumnNames</param>
public DataRowEqualityComparer(params string[] ColumnNames)
{
this.ColumnNames = ColumnNames;
}
bool HasColumn(DataRow dr, string ColumnName)
{
return dr.Table != null && dr.Table.Columns.Contains(ColumnName);
}
/// <summary>
/// 接口实现
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
public bool Equals(DataRow x, DataRow y)
{
if (Object.ReferenceEquals(x, y)) return true;
if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
return false;
return ColumnNames.All(c =>
HasColumn(x, c) ? object.Equals(x[c], y[c]) : true
);
}
/// <summary>
/// 接口实现
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public int GetHashCode(DataRow obj)
{
if (Object.ReferenceEquals(obj, null)) return 0;
int hashTobj = 0;
ColumnNames.All(c =>
{
//var hp = HasProperties(p.PropertyType);
//var v = p.GetValue(obj);
//var hc = v.GetHashCode();
if (hashTobj == 0)
{
hashTobj = HasColumn(obj, c) ? obj[c].GetHashCode() : 0;
}
else
{
hashTobj ^= HasColumn(obj, c) ? obj[c].GetHashCode() : 0;
}
return true;
});
return hashTobj;
}
}
}