@@ -32,18 +32,41 @@ public static IQueryable Where(this IQueryable source, string predicate, params
32
32
source . Expression , Expression . Quote ( lambda ) ) ) ;
33
33
}
34
34
35
- public static IQueryable Select ( this IQueryable source , string selector , params object [ ] values )
35
+ //public static IQueryable Select(this IQueryable source, string selector, params object[] values)
36
+ //{
37
+ // if (source == null) throw new ArgumentNullException("source");
38
+ // if (selector == null) throw new ArgumentNullException("selector");
39
+ // LambdaExpression lambda = DynamicExpression.ParseLambda(source.ElementType, null, selector, values);
40
+ // return source.Provider.CreateQuery(
41
+ // Expression.Call(
42
+ // typeof(Queryable), "Select",
43
+ // new Type[] { source.ElementType, lambda.Body.Type },
44
+ // source.Expression, Expression.Quote(lambda)));
45
+ //}
46
+
47
+ // https://code.google.com/p/dynamic-linq/
48
+ public static IQueryable Select ( this IQueryable source , Type type , string selector , params object [ ] values )
36
49
{
37
50
if ( source == null ) throw new ArgumentNullException ( "source" ) ;
38
51
if ( selector == null ) throw new ArgumentNullException ( "selector" ) ;
39
- LambdaExpression lambda = DynamicExpression . ParseLambda ( source . ElementType , null , selector , values ) ;
52
+ LambdaExpression lambda = DynamicExpression . ParseLambda ( source . ElementType , type , selector , values ) ;
40
53
return source . Provider . CreateQuery (
41
54
Expression . Call (
42
55
typeof ( Queryable ) , "Select" ,
43
56
new Type [ ] { source . ElementType , lambda . Body . Type } ,
44
57
source . Expression , Expression . Quote ( lambda ) ) ) ;
45
58
}
46
59
60
+ public static IQueryable Select ( this IQueryable source , string selector , params object [ ] values )
61
+ {
62
+ return Select ( source , null , selector , values ) ;
63
+ }
64
+
65
+ public static IQueryable < T > Select < T > ( this IQueryable source , string selector , params object [ ] values )
66
+ {
67
+ return Select ( source , typeof ( T ) , selector , values ) as IQueryable < T > ;
68
+ }
69
+
47
70
public static IQueryable < T > OrderBy < T > ( this IQueryable < T > source , string ordering , params object [ ] values )
48
71
{
49
72
return ( IQueryable < T > ) OrderBy ( ( IQueryable ) source , ordering , values ) ;
@@ -123,6 +146,52 @@ public static int Count(this IQueryable source)
123
146
typeof ( Queryable ) , "Count" ,
124
147
new Type [ ] { source . ElementType } , source . Expression ) ) ;
125
148
}
149
+
150
+ // http://stackoverflow.com/questions/17490080/how-to-do-a-sum-using-dynamic-linq
151
+ public static object Aggregate ( this IQueryable source , string function , string member )
152
+ {
153
+ if ( source == null ) throw new ArgumentNullException ( "source" ) ;
154
+ if ( member == null ) throw new ArgumentNullException ( "member" ) ;
155
+
156
+ // Properties
157
+ PropertyInfo property = source . ElementType . GetProperty ( member ) ;
158
+ ParameterExpression parameter = Expression . Parameter ( source . ElementType , "s" ) ;
159
+ Expression selector = Expression . Lambda ( Expression . MakeMemberAccess ( parameter , property ) , parameter ) ;
160
+ // We've tried to find an expression of the type Expression<Func<TSource, TAcc>>,
161
+ // which is expressed as ( (TSource s) => s.Price );
162
+
163
+ var methods = typeof ( Queryable ) . GetMethods ( ) . Where ( x => x . Name == function ) ;
164
+
165
+ // Method
166
+ MethodInfo aggregateMethod = typeof ( Queryable ) . GetMethods ( ) . SingleOrDefault (
167
+ m => m . Name == function
168
+ && m . ReturnType == property . PropertyType // should match the type of the property
169
+ && m . IsGenericMethod ) ;
170
+
171
+ // Sum, Average
172
+ if ( aggregateMethod != null )
173
+ {
174
+ return source . Provider . Execute (
175
+ Expression . Call (
176
+ null ,
177
+ aggregateMethod . MakeGenericMethod ( new [ ] { source . ElementType } ) ,
178
+ new [ ] { source . Expression , Expression . Quote ( selector ) } ) ) ;
179
+ }
180
+ // Min, Max
181
+ else
182
+ {
183
+ aggregateMethod = typeof ( Queryable ) . GetMethods ( ) . SingleOrDefault (
184
+ m => m . Name == function
185
+ && m . GetGenericArguments ( ) . Length == 2
186
+ && m . IsGenericMethod ) ;
187
+
188
+ return source . Provider . Execute (
189
+ Expression . Call (
190
+ null ,
191
+ aggregateMethod . MakeGenericMethod ( new [ ] { source . ElementType , property . PropertyType } ) ,
192
+ new [ ] { source . Expression , Expression . Quote ( selector ) } ) ) ;
193
+ }
194
+ }
126
195
}
127
196
128
197
public abstract class DynamicClass
0 commit comments