Linq Coding -- Part Eight (Equals Topic)
首先说一下同等联接,大家一般都知道Join Clause执行的其实是同等联接。
那是什么是同等联接呢?
同等联接:就是只能在两个键(外键、内键)之间的相等关系Match。而其他类型的比较(比如,"greater than","less than"
或者"not equals")都是不支持。
嗯!/,为了表明所有联接即是同等联接,Join Clause Using equals key word is not "==" operator.
equals is only using join clause,并且它与 == 运算符之间存在一个重要区别。
那重要区别到底指什么呢?
首先要知道Linq中的equals关键字,只是一个Code snippet,其实就是implementing Equals Method
以下是equals Code snippet:
2 if (obj == null || GetType() != obj.GetType()) {
3 return false;
4 }
5 // TODO: write your implementation of Equals() here
6 throw new $Exception$();
7 return base.Equals (obj);$end$
8 }
9
10 // override object.GetHashCode
11 public override int GetHashCode() {
12 // TODO: write your implementation of GetHashCode() here
13 throw new $Exception$();
14 return base.GetHashCode();
15 }]]>
16
好了,明白了这些,其实它们的区别,我可以用两句话说明
1.Equals 方法只是在 System.Object 中定义的一个虚拟方法,它由任何选择执行该任务的类所重写;== 运算符是一个可由类
重载的运算符,该类通常具有恒等行为。
2.二者之间的主要区别就是在于多态表现上,Equals方法是重写,而==运算符是被重载。这意味着除非编译器知道invoke更为具
体的版本,否则它只是调用恒等版本。
嗯,对于Linq中equals,比如看看这句:
on p.FirstName equals pp.Owner.FirstName
p.FirstName为外部源序列,而pp.Owner.FirstName则是内部源序列;所以简单的理解,左键就是表示外部源序列,反之右键就是表示内部源序列;反正了解就是。那更多的 equals & == 的Code,可以参见 GroupJoin 中的2,3两段代码 queryForLinq,queryForLinq2
Wow,接下来我们继续聊聊Equals相关方法,看看这几个Equals方法
1.SequenceEqual()
2.GreaterThanOrEqual()
3.LessThanOrEqual()
4.NotEqual()
SequenceEqual(): 根据相等比较器确定两个序列是否相等。
它有两个重载方法,1.通过使用相应类型的默认相等比较器对序列的元素进行比较,以确定两个序列是否相等。
2.使用指定的 IEqualityComparer<(Of <(T>)>) 对两个序列的元素进行比较,以确定序列是否相等。
*以下是两个重载方法应用的DEMO
1 public class Equal {
2 public void SequenceEqual() {
3 Product p = new Product { CategoryID = 1, Name = "111" };
4 Product pp = new Product { CategoryID = 2, Name = "222" };
5 Product ppp = new Product { CategoryID = 2, Name = "222" };
6
7 ///比较的数据源
8 List<Product> ps = new List<Product> { p, pp };
9 List<Product> pps = new List<Product> { p, pp, ppp };
10
11 ///第一种重载
12 Boolean equal = ps.SequenceEqual(pps);
13
14 Console.WriteLine(equal ? "are" : "are not");
15
18 ///第二种重载:实现IEqualityComparer接口
19 IEnumerable<Product> str = ps;
20 IEnumerable<Product> str1 = pps;
23
24 ObjectCompare objectCompare = new ObjectCompare();
27
28 Boolean equality = ps.SequenceEqual(pps, objectCompare);
29
30 Console.WriteLine(equal ? "are" : "are not");
31
32 ///第一种重载,只是换了一种数据源
33 IEnumerable<Int32> values = Enumerable.Range(0, 10);
34 IEnumerable<Int32> sequence = Enumerable.Range(0, 5)
.Concat(Enumerable.Range(5, 5));
35
36 Boolean sequenceEqual = values.SequenceEqual(sequence);
37 Console.WriteLine(sequenceEqual);
38 }
39
40 /// <summary>
41 /// 第二种重载:实现IEqualityComparer接口
42 /// </summary>
43 public class ObjectCompare : IEqualityComparer<Product> {
44 #region IEqualityComparer<Product> Members
45
46 public bool Equals(Product x, Product y) {
47 return x == y;
48 }
49
50 public int GetHashCode(Product obj) {
51 string s = String.Format("{0}{1}", obj.Name,
obj.CategoryID.ToString());
52 return s.GetHashCode();
53 }
55 #endregion
56 }
57 }
GreaterThanOrEqual():创建一个表示“大于或等于”数值比较的 BinaryExpression。可指定实现方法。
Demo:
BinaryExpression greaterThanOrEqual =
Expression.GreaterThanOrEqual(Expression.Constant(3.0),
Expression.Constant(9.0));
Console.WriteLine(greaterThanOrEqual.ToString());
LessThanOrEqual:创建一个表示“小于或等于”数值比较的 BinaryExpression。
Demo:
BinaryExpression lessThanOrEqual =
Expression.LessThanOrEqual(Expression.Constant(7.0),
Expression.Constant(7.0));
Console.WriteLine(lessThanOrEqual.ToString());
NotEqual:创建一个表示不相等比较的 BinaryExpression。
Demo:
BinaryExpression notEqual =
Expression.NotEqual(Expression.Constant(41.0), Expression.Constant(42.0));
Console.WriteLine(notEqual.ToString());
LINQ Coding 目录
- Linq Coding -- Part One
- Linq Coding -- Part Two[标准查询运算符]
- Linq Coding -- Part Three [Let子句]
- Linq Coding -- Part Four[Concat应用]
- Linq Coding -- Part Five (Join之内部联接查询)
- Linq Coding -- Part Six (Join之分组联接)
- Linq Coding -- Part Seven (Join之左外部联接、DefaultIfEmpty、GroupJoin)
- Linq Coding -- Part Eight (Equals Topic)