7
7
8
8
namespace NHibernate . Linq . Visitors . ResultOperatorProcessors
9
9
{
10
- public class ProcessNonAggregatingGroupBy : IResultOperatorProcessor < NonAggregatingGroupBy >
11
- {
12
- public void Process ( NonAggregatingGroupBy resultOperator , QueryModelVisitor queryModelVisitor , IntermediateHqlTree tree )
13
- {
14
- var tSource = queryModelVisitor . Model . SelectClause . Selector . Type ;
15
- var tKey = resultOperator . GroupBy . KeySelector . Type ;
16
- var tElement = resultOperator . GroupBy . ElementSelector . Type ;
10
+ public class ProcessNonAggregatingGroupBy : IResultOperatorProcessor < NonAggregatingGroupBy >
11
+ {
12
+ public void Process ( NonAggregatingGroupBy resultOperator , QueryModelVisitor queryModelVisitor , IntermediateHqlTree tree )
13
+ {
14
+ var tSource = queryModelVisitor . Model . SelectClause . Selector . Type ;
15
+ var tKey = resultOperator . GroupBy . KeySelector . Type ;
16
+ var tElement = resultOperator . GroupBy . ElementSelector . Type ;
17
17
18
- // Stuff in the group by that doesn't map to HQL. Run it client-side
19
- var listParameter = Expression . Parameter ( typeof ( IEnumerable < object > ) , "list" ) ;
18
+ // Stuff in the group by that doesn't map to HQL. Run it client-side
19
+ var listParameter = Expression . Parameter ( typeof ( IEnumerable < object > ) , "list" ) ;
20
20
21
- ParameterExpression itemParam = Expression . Parameter ( tSource , "item" ) ;
22
- Expression keySelectorSource = itemParam ;
21
+ var keySelectorExpr = CreateSelector ( tSource , resultOperator . GroupBy . KeySelector ) ;
23
22
24
- if ( tSource != SourceOf ( resultOperator . GroupBy . KeySelector ) )
25
- {
26
- keySelectorSource = Expression . MakeMemberAccess ( itemParam ,
27
- tSource . GetMember (
28
- ( ( QuerySourceReferenceExpression )
29
- resultOperator . GroupBy . KeySelector ) . ReferencedQuerySource .
30
- ItemName ) [ 0 ] ) ;
31
- }
23
+ var elementSelectorExpr = CreateSelector ( tSource , resultOperator . GroupBy . ElementSelector ) ;
32
24
25
+ var groupByMethod = EnumerableHelper . GetMethod ( "GroupBy" ,
26
+ new [ ] { typeof ( IEnumerable < > ) , typeof ( Func < , > ) , typeof ( Func < , > ) } ,
27
+ new [ ] { tSource , tKey , tElement } ) ;
33
28
34
- Expression keySelector = new GroupByKeySelectorVisitor ( keySelectorSource ) . Visit ( resultOperator . GroupBy . KeySelector ) ;
29
+ var castToItem = EnumerableHelper . GetMethod ( "Cast" , new [ ] { typeof ( IEnumerable ) } , new [ ] { tSource } ) ;
35
30
36
- Expression elementSelectorSource = itemParam ;
31
+ var toList = EnumerableHelper . GetMethod ( "ToList" , new [ ] { typeof ( IEnumerable < > ) } , new [ ] { resultOperator . GroupBy . ItemType } ) ;
37
32
38
- if ( tSource != SourceOf ( resultOperator . GroupBy . ElementSelector ) )
39
- {
40
- elementSelectorSource = Expression . MakeMemberAccess ( itemParam ,
41
- tSource . GetMember (
42
- ( ( QuerySourceReferenceExpression )
43
- resultOperator . GroupBy . ElementSelector ) . ReferencedQuerySource .
44
- ItemName ) [ 0 ] ) ;
45
- }
33
+ Expression castToItemExpr = Expression . Call ( castToItem , listParameter ) ;
46
34
47
- Expression elementSelector = new GroupByKeySelectorVisitor ( elementSelectorSource ) . Visit ( resultOperator . GroupBy . ElementSelector ) ;
35
+ var groupByExpr = Expression . Call ( groupByMethod , castToItemExpr , keySelectorExpr , elementSelectorExpr ) ;
48
36
49
- var groupByMethod = EnumerableHelper . GetMethod ( "GroupBy" ,
50
- new [ ] { typeof ( IEnumerable < > ) , typeof ( Func < , > ) , typeof ( Func < , > ) } ,
51
- new [ ] { tSource , tKey , tElement } ) ;
37
+ var toListExpr = Expression . Call ( toList , groupByExpr ) ;
52
38
53
- var castToItem = EnumerableHelper . GetMethod ( "Cast" , new [ ] { typeof ( IEnumerable ) } , new [ ] { tSource } ) ;
39
+ var lambdaExpr = Expression . Lambda ( toListExpr , listParameter ) ;
54
40
55
- var toList = EnumerableHelper . GetMethod ( "ToList" , new [ ] { typeof ( IEnumerable < > ) } , new [ ] { resultOperator . GroupBy . ItemType } ) ;
41
+ tree . AddListTransformer ( lambdaExpr ) ;
42
+ }
56
43
57
- LambdaExpression keySelectorExpr = Expression . Lambda ( keySelector , itemParam ) ;
44
+ private static LambdaExpression CreateSelector ( System . Type sourceType , Expression selector )
45
+ {
46
+ var parameter = Expression . Parameter ( sourceType , "item" ) ;
47
+ var selectorSource = ( Expression ) parameter ;
58
48
59
- LambdaExpression elementSelectorExpr = Expression . Lambda ( elementSelector , itemParam ) ;
49
+ if ( sourceType != SourceOf ( selector ) )
50
+ {
51
+ var member = sourceType . GetMember ( ( ( QuerySourceReferenceExpression ) selector ) . ReferencedQuerySource . ItemName ) [ 0 ] ;
60
52
61
- Expression castToItemExpr = Expression . Call ( castToItem , listParameter ) ;
53
+ selectorSource = Expression . MakeMemberAccess ( parameter , member ) ;
54
+ }
62
55
63
- var groupByExpr = Expression . Call ( groupByMethod , castToItemExpr , keySelectorExpr , elementSelectorExpr ) ;
56
+ var keySelector = new GroupByKeySelectorVisitor ( selectorSource ) . Visit ( selector ) ;
57
+ return Expression . Lambda ( keySelector , parameter ) ;
58
+ }
64
59
65
- var toListExpr = Expression . Call ( toList , groupByExpr ) ;
66
-
67
- var lambdaExpr = Expression . Lambda ( toListExpr , listParameter ) ;
68
-
69
- tree . AddListTransformer ( lambdaExpr ) ;
70
- }
71
-
72
- private static System . Type SourceOf ( Expression keySelector )
73
- {
74
- return new GroupByKeySourceFinder ( ) . Visit ( keySelector ) . Type ;
75
- }
76
- }
77
- }
60
+ private static System . Type SourceOf ( Expression keySelector )
61
+ {
62
+ return new GroupByKeySourceFinder ( ) . Visit ( keySelector ) . Type ;
63
+ }
64
+ }
65
+ }
0 commit comments