GroupJoin和Join的声明及调用
public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>(this IEnumerable<TOuter> outer, IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector);
// 假设有这两个集合 studs ; classes; 注意,两个集合的类型TOuter和TInner是可以不一样的,两个key未必要有连系,可以比较就行。
// 即,下面的 inner.ClassId可以是 inner.GradeId, 但是要有实际意义,否则就是瞎写。 两个key的比较方式默认是比较是否相等。但是可以自己写比较器。
// 调用方式为:
// studs.Join(classes,outer=>outer.ClassId,inner=>inner.ClassId,(stud,cls)=>new{StudentId=stud.StudentId,GradeId=cls.GradeId});
// 其功能就是通过两张表的某个字段进行比较,这两个字段相等(默认)则选出这两条记录,将两条记录联合增减后得到新类型的记录,然后继续Outer表的游标不变,继续查找
// Inner表的下一条记录,直到把Inner表的记录查找完毕;然后才取出Outer表的下一条记录。这里类似两层 for循环
// 于Inner表的记录进行比较,有符合的则又将它们联合增减,如果没有符合的,则不会选出记录进行联合,因为传给第三个委托是需要 两个参数的,这两个参数就是通过查找获得
// 没有查找到自然没办法联合。 故Join(...)返回的 IEnumerable<TResult> s, s的元素个数是不定的,与 两张表和 两个关键字,及比较方式都有关系。
// Join不仅可以用于将两个不同的表关联,还可以将一个表进行自关联,即Outer表和Inner表是一张表。
// 实现方式类似:
foreach(var stud in studs)
{
var key1=outerKeySelector(stud);
foreach(var cls in classes) // 关键点在这里,它并不是说找到第一个就break,而是全部都找,符合的都添加到返回的list中
{
var key2=innerKeySelector(cls);
if(key1==key2)
{
list.Add(resultSelector(stud,cls));
}
}
}
return list; //
再来看GroupJoin的声明:
public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult>(this IEnumerable<TOuter> outer, IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector); // 这里的IEnumerable<TInner>就是和声明Join有很大的不同
// 这里 IEnumerable<TInner> listForOuterKey是 在Inner表中找出所有记录的innerKey匹配上一层outerKey的记录组成一个 IEnumerable<TInner> blockInnerList
// 所以,GroupJoin的Outer和Inner是有调用与被调用之分的。 这里resultSelector中对 blockInnerList的利用一般也是 num=blockInnerList.Count();等等
posted on 2015-08-31 17:19 Silentdoer 阅读(599) 评论(0) 编辑 收藏 举报