@@ -92,38 +92,44 @@ Expression MakeAggregatingProjection(Expression target, Type groupingType, int g
9292
9393 IEnumerable < Expression > MakeAggregates ( Expression aggregateTarget , IEnumerable < SummaryInfo > summary ) {
9494 foreach ( var s in TransformSummary ( summary ) ) {
95- var itemParam = CreateItemParam ( typeof ( T ) ) ;
96- var selectorExpr = CompileAccessorExpression ( itemParam , s . Selector , liftToNullable : true ) ;
97- var selectorType = selectorExpr . Type ;
98-
99- var callType = typeof ( Enumerable ) ;
100- var isCountNotNull = s . SummaryType == AggregateName . COUNT_NOT_NULL ;
101-
102- if ( isCountNotNull && Utils . CanAssignNull ( selectorType ) ) {
103- yield return Expression . Call (
104- callType ,
105- nameof ( Enumerable . Sum ) ,
106- Type . EmptyTypes ,
107- Expression . Call (
108- typeof ( Enumerable ) ,
109- nameof ( Enumerable . Select ) ,
110- new [ ] { typeof ( T ) , typeof ( int ) } ,
111- aggregateTarget ,
112- Expression . Lambda (
113- Expression . Condition (
114- Expression . NotEqual ( selectorExpr , Expression . Constant ( null , selectorType ) ) ,
115- Expression . Constant ( 1 ) ,
116- Expression . Constant ( 0 )
117- ) ,
118- itemParam
119- )
95+ yield return MakeAggregate ( aggregateTarget , s ) ;
96+ }
97+ }
98+
99+ Expression MakeAggregate ( Expression aggregateTarget , SummaryInfo s ) {
100+ var itemParam = CreateItemParam ( typeof ( T ) ) ;
101+ var selectorExpr = CompileAccessorExpression ( itemParam , s . Selector , liftToNullable : true ) ;
102+ var selectorType = selectorExpr . Type ;
103+
104+ var callType = typeof ( Enumerable ) ;
105+ var isCountNotNull = s . SummaryType == AggregateName . COUNT_NOT_NULL ;
106+
107+ if ( isCountNotNull && Utils . CanAssignNull ( selectorType ) ) {
108+ return Expression . Call (
109+ callType ,
110+ nameof ( Enumerable . Sum ) ,
111+ Type . EmptyTypes ,
112+ Expression . Call (
113+ typeof ( Enumerable ) ,
114+ nameof ( Enumerable . Select ) ,
115+ new [ ] { typeof ( T ) , typeof ( int ) } ,
116+ aggregateTarget ,
117+ Expression . Lambda (
118+ Expression . Condition (
119+ Expression . NotEqual ( selectorExpr , Expression . Constant ( null , selectorType ) ) ,
120+ Expression . Constant ( 1 ) ,
121+ Expression . Constant ( 0 )
122+ ) ,
123+ itemParam
120124 )
121- ) ;
122- } else {
123- var callMethod = GetPreAggregateMethodName ( s . SummaryType ) ;
124- var callMethodTypeParams = new List < Type > { typeof ( T ) } ;
125- var callArgs = new List < Expression > { aggregateTarget } ;
125+ )
126+ ) ;
127+ } else {
128+ var callMethod = GetPreAggregateMethodName ( s . SummaryType ) ;
129+ var callMethodTypeParams = new List < Type > { typeof ( T ) } ;
130+ var callArgs = new List < Expression > { aggregateTarget } ;
126131
132+ try {
127133 if ( ! IsWellKnownAggregateDataType ( selectorType ) ) {
128134 if ( s . SummaryType == AggregateName . MIN || s . SummaryType == AggregateName . MAX ) {
129135 callMethodTypeParams . Add ( selectorType ) ;
@@ -140,7 +146,10 @@ IEnumerable<Expression> MakeAggregates(Expression aggregateTarget, IEnumerable<S
140146 if ( ! isCountNotNull )
141147 callArgs . Add ( Expression . Lambda ( selectorExpr , itemParam ) ) ;
142148
143- yield return Expression . Call ( callType , callMethod , callMethodTypeParams . ToArray ( ) , callArgs . ToArray ( ) ) ;
149+ return Expression . Call ( callType , callMethod , callMethodTypeParams . ToArray ( ) , callArgs . ToArray ( ) ) ;
150+ } catch ( Exception x ) {
151+ var message = $ "Failed to translate the '{ s . SummaryType } ' aggregate for the '{ s . Selector } ' member ({ selectorExpr . Type } ). See InnerException for details.";
152+ throw new Exception ( message , x ) ;
144153 }
145154 }
146155 }
@@ -184,6 +193,12 @@ static string GetPreAggregateMethodName(string summaryType) {
184193 return nameof ( Enumerable . Count ) ;
185194 }
186195
196+ if ( CustomAggregators . IsRegistered ( summaryType ) ) {
197+ var message = $ "The custom aggregate '{ summaryType } ' cannot be translated to a LINQ expression."
198+ + $ " Set { nameof ( DataSourceLoadOptionsBase ) } .{ nameof ( DataSourceLoadOptionsBase . RemoteGrouping ) } to False to enable in-memory aggregate calculation.";
199+ throw new InvalidOperationException ( message ) ;
200+ }
201+
187202 throw new NotSupportedException ( ) ;
188203 }
189204
0 commit comments