对于类型的对比,linq原来的对比是区分不了的。
对两个list进行查询交集方法。交集,并集的函数是直接用Linq的,这里不再写。
List<T> intersectList = queryList.AsQueryable().Intersect(sqlList, new ListEquality<T>()).ToList();
1 public class ListEquality<T> : IEqualityComparer<T> where T : new() 2 { 3 4 PropertyInfo[] propertys = typeof(T).GetProperties().Where(p => p.Name != "ParamInfo").Where(p => p.Name != "State").ToArray(); 5 6 7 public bool Equals(T x, T y) 8 { 9 foreach (var pe in propertys) 10 { 11 object o_x = pe.GetValue(x, null); 12 object o_y = pe.GetValue(y, null); 13 if (!object.Equals(o_x, o_y)) 14 { 15 return false; 16 } 17 } 18 return true; 19 } 20 21 public int GetHashCode(T obj) 22 { 23 if (obj == null) 24 { 25 return 0; 26 } 27 else 28 { 29 return obj.ToString().GetHashCode(); 30 } 31 } 32 }
上面的代码明显是根据排除字段来对比的。如果你不想根据字段对比,那就不要排除。
通过主键属性来对比仅仅是主键的类
1 public class ListKeyEquality<T> : IEqualityComparer<T> where T : new() 2 { 3 4 PropertyInfo[] propertys = typeof(T).GetProperties().Where(p => p.Name != "ParamInfo").Where(p => p.Name != "State").ToArray(); 5 public bool Equals(T x, T y) 6 { 7 foreach (var pe in propertys) 8 { 9 object[] allAttributes = pe.GetCustomAttributes(false); 10 if (allAttributes.Count() == 0) 11 { 12 continue; 13 } 14 if ((allAttributes.FirstOrDefault() as GrantAttribute).IsKey) 15 { 16 object o_x = pe.GetValue(x, null); 17 object o_y = pe.GetValue(y, null); 18 if (!object.Equals(o_x, o_y)) 19 { 20 return false; 21 } 22 } 23 24 } 25 return true; 26 } 27 28 public int GetHashCode(T obj) 29 { 30 if (obj == null) 31 { 32 return 0; 33 } 34 else 35 { 36 return obj.ToString().GetHashCode(); 37 } 38 } 39 }
1 public class GrantAttribute : Attribute 2 { 3 /// <summary> 4 /// 是否xml类型 5 /// </summary> 6 public bool CheckXml { get; set; } 7 /// <summary> 8 /// 是否主键 9 /// </summary> 10 public bool IsKey { get; set; } 11 }
类的主键属性调用也是很简单
public class OrderInfo { /// <summary> /// 本系统订单ID /// </summary> [Grant(IsKey = true)] public Guid OrderId { get; set; } }