Continuing the Dynamic LINQ series, here are some hopefuly useful methods for performing LINQ queries in IQueryable or IQueryable<T>
object, with String parameters. The available methods, so far, are:
- GroupBy
- OrderBy
- Skip
- Take
- WhereEquals
- WhereNotEquals
1
public
static
class
QueryableExtensions
2 {
3 public static IQueryable < T &> WhereNotEquals < T &> ( this IQueryable < T &> query, String propertyName, Object value)
4 {
5 return (WhereNotEquals(query as IQueryable, propertyName, value) as IQueryable < T &> );
6 }
7
8 public static IQueryable WhereNotEquals( this IQueryable query, String propertyName, Object value)
9 {
10 Type propertyType = query.GetType().GetGenericArguments() [ 0 ];
11 MethodInfo whereMethod = typeof (Queryable).GetMethods(BindingFlags.Public | BindingFlags.Static).Where(m => m.Name == " Where " ).ToArray() [ 0 ].MakeGenericMethod(propertyType);
12
13 ParameterExpression parameter = Expression.Parameter
14 (
15 propertyType,
16 " m "
17 );
18
19 MemberExpression member = Expression.MakeMemberAccess
20 (
21 parameter,
22 propertyType.GetProperty(propertyName)
23 );
24
25 BinaryExpression equal = ParameterExpression.NotEqual
26 (
27 member,
28 (value != null ) ? Expression.Constant(value, value.GetType()) : null
29 );
30
31 LambdaExpression lambda = Expression.Lambda
32 (
33 typeof (Func < , > ).MakeGenericType(propertyType, typeof (Boolean)),
34 equal,
35 member.Expression as ParameterExpression
36 );
37
38 query = whereMethod.Invoke( null , new Object [] { query, lambda }) as IQueryable;
39
40 return (query);
41 }
42
43 public static IQueryable < T &> WhereEquals < T &> ( this IQueryable < T &> query, String propertyName, Object value)
44 {
45 return (WhereEquals(query as IQueryable, propertyName, value) as IQueryable < T &> );
46 }
47
48 public static IQueryable WhereEquals( this IQueryable query, String propertyName, Object value)
49 {
50 Type propertyType = query.GetType().GetGenericArguments() [ 0 ];
51 MethodInfo whereMethod = typeof (Queryable).GetMethods(BindingFlags.Public | BindingFlags.Static).Where(m => m.Name == " Where " ).ToArray() [ 0 ].MakeGenericMethod(propertyType);
52
53 ParameterExpression parameter = Expression.Parameter
54 (
55 propertyType,
56 " m "
57 );
58
59 MemberExpression member = Expression.MakeMemberAccess
60 (
61 parameter,
62 propertyType.GetProperty(propertyName)
63 );
64
65 BinaryExpression equal = ParameterExpression.Equal
66 (
67 member,
68 (value != null ) ? Expression.Constant(value, value.GetType()) : null
69 );
70
71 LambdaExpression lambda = Expression.Lambda( typeof (Func < , > ).MakeGenericType(propertyType, typeof (Boolean)), equal, member.Expression as ParameterExpression);
72
73 query = whereMethod.Invoke( null , new Object[]{ query, lambda }) as IQueryable;
74
75 return (query);
76 }
77
78 public static IQueryable < T &> GroupBy < T &> ( this IQueryable < T &> query, String propertyName)
79 {
80 return (GroupBy(query as IQueryable, propertyName) as IQueryable < T &> );
81 }
82
83 public static IQueryable GroupBy( this IQueryable query, String propertyName)
84 {
85 Type propertyType = query.GetType().GetGenericArguments() [ 0 ];
86 PropertyInfo property = propertyType.GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public);
87 MethodInfo groupByMethod = typeof (Queryable).GetMethods(BindingFlags.Public | BindingFlags.Static).Where(m => m.Name == " GroupBy " && m.GetParameters().Length == 2 ).ToArray() [ 0 ].MakeGenericMethod(propertyType, property.PropertyType);
88
89 ParameterExpression parameter = Expression.Parameter
90 (
91 propertyType,
92 " m "
93 );
94
95 MemberExpression member = Expression.MakeMemberAccess
96 (
97 parameter,
98 propertyType.GetProperty(propertyName)
99 );
100
101 LambdaExpression lambda = Expression.Lambda
102 (
103 typeof (Func < , > ).MakeGenericType(propertyType, property.PropertyType),
104 member,
105 member.Expression as ParameterExpression
106 );
107
108 query = groupByMethod.Invoke( null , new Object [] { query, lambda }) as IQueryable;
109
110 return (query);
111 }
112
113 public static IQueryable < T &> OrderBy < T &> ( this IQueryable < T &> query, params String [] properties)
114 {
115 return (OrderBy(query as IQueryable, properties) as IQueryable < T &> );
116 }
117
118 public static IQueryable OrderBy( this IQueryable query, params String [] properties)
119 {
120 properties = (properties == null ) ? new String [ 0 ] : properties.Distinct().ToArray();
121
122 Type propertyType = query.GetType().GetGenericArguments()[ 0 ];
123 MethodInfo orderByMethod = typeof (Queryable).GetMethods(BindingFlags.Public | BindingFlags.Static).Where(m => m.Name == " OrderBy " ).ToArray() [ 0 ];
124 MethodInfo orderByDescMethod = typeof (Queryable).GetMethods(BindingFlags.Public | BindingFlags.Static).Where(m => m.Name == " OrderByDescending " ).ToArray() [ 0 ];
125 MethodInfo orderThenByMethod = typeof (Queryable).GetMethods(BindingFlags.Public | BindingFlags.Static).Where(m => m.Name == " ThenBy " ).ToArray() [ 0 ];
126 MethodInfo orderThenByDescMethod = typeof (Queryable).GetMethods(BindingFlags.Public | BindingFlags.Static).Where(m => m.Name == " ThenByDescending " ).ToArray() [ 0 ];
127 String [] parts = null ;
128 MethodInfo method = null ;
129 PropertyInfo property = null ;
130 MemberExpression member = null ;
131 LambdaExpression orderBy = null ;
132
133 for (Int32 i = 0 ; i < properties.Length; ++ i)
134 {
135 parts = properties[ i ].Split( ' ' );
136
137 property = propertyType.GetProperty(parts[ 0 ], BindingFlags.Instance | BindingFlags.Public);
138
139 if ((parts.Length == 1 ) || (parts [ 1 ].Equals( " asc " , StringComparison.OrdinalIgnoreCase) == true ))
140 {
141 if (i == 0 )
142 {
143 method = orderByMethod.MakeGenericMethod(propertyType, property.PropertyType);
144 }
145 else
146 {
147 method = orderThenByMethod.MakeGenericMethod(propertyType, property.PropertyType);
148 }
149 }
150 else if (parts[ 1 ].Equals( " desc " , StringComparison.OrdinalIgnoreCase) == true )
151 {
152 if (i == 0 )
153 {
154 method = orderByDescMethod.MakeGenericMethod(propertyType, property.PropertyType);
155 }
156 else
157 {
158 method = orderThenByDescMethod.MakeGenericMethod(propertyType, property.PropertyType);
159 }
160 }
161
162 member = Expression.MakeMemberAccess
163 (
164 Expression.Parameter(propertyType, " n " ),
165 property
166 );
167
168 orderBy = Expression.Lambda
169 (
170 member,
171 member.Expression as ParameterExpression
172 );
173
174 query = method.Invoke( null , new Object [] { query, orderBy }) as IQueryable;
175 }
176
177 return (query);
178 }
179
180 public static IQueryable Take( this IQueryable query, Int32 pageSize)
181 {
182 Type propertyType = query.GetType().GetGenericArguments() [ 0 ];
183 MethodInfo takeMethod = typeof (Queryable).GetMethod( " Take " , BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(propertyType);
184
185 query = takeMethod.Invoke( null , new Object [] { query, pageSize }) as IQueryable;
186
187 return (query);
188 }
189
190 public static IQueryable Skip( this IQueryable query, Int32 pageIndex)
191 {
192 Type propertyType = query.GetType().GetGenericArguments() [ 0 ];
193 MethodInfo skipMethod = typeof (Queryable).GetMethod( " Skip " , BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(propertyType);
194
195 query = skipMethod.Invoke( null , new Object [] { query, pageIndex }) as IQueryable;
196
197 return (query);
198 }
2 {
3 public static IQueryable < T &> WhereNotEquals < T &> ( this IQueryable < T &> query, String propertyName, Object value)
4 {
5 return (WhereNotEquals(query as IQueryable, propertyName, value) as IQueryable < T &> );
6 }
7
8 public static IQueryable WhereNotEquals( this IQueryable query, String propertyName, Object value)
9 {
10 Type propertyType = query.GetType().GetGenericArguments() [ 0 ];
11 MethodInfo whereMethod = typeof (Queryable).GetMethods(BindingFlags.Public | BindingFlags.Static).Where(m => m.Name == " Where " ).ToArray() [ 0 ].MakeGenericMethod(propertyType);
12
13 ParameterExpression parameter = Expression.Parameter
14 (
15 propertyType,
16 " m "
17 );
18
19 MemberExpression member = Expression.MakeMemberAccess
20 (
21 parameter,
22 propertyType.GetProperty(propertyName)
23 );
24
25 BinaryExpression equal = ParameterExpression.NotEqual
26 (
27 member,
28 (value != null ) ? Expression.Constant(value, value.GetType()) : null
29 );
30
31 LambdaExpression lambda = Expression.Lambda
32 (
33 typeof (Func < , > ).MakeGenericType(propertyType, typeof (Boolean)),
34 equal,
35 member.Expression as ParameterExpression
36 );
37
38 query = whereMethod.Invoke( null , new Object [] { query, lambda }) as IQueryable;
39
40 return (query);
41 }
42
43 public static IQueryable < T &> WhereEquals < T &> ( this IQueryable < T &> query, String propertyName, Object value)
44 {
45 return (WhereEquals(query as IQueryable, propertyName, value) as IQueryable < T &> );
46 }
47
48 public static IQueryable WhereEquals( this IQueryable query, String propertyName, Object value)
49 {
50 Type propertyType = query.GetType().GetGenericArguments() [ 0 ];
51 MethodInfo whereMethod = typeof (Queryable).GetMethods(BindingFlags.Public | BindingFlags.Static).Where(m => m.Name == " Where " ).ToArray() [ 0 ].MakeGenericMethod(propertyType);
52
53 ParameterExpression parameter = Expression.Parameter
54 (
55 propertyType,
56 " m "
57 );
58
59 MemberExpression member = Expression.MakeMemberAccess
60 (
61 parameter,
62 propertyType.GetProperty(propertyName)
63 );
64
65 BinaryExpression equal = ParameterExpression.Equal
66 (
67 member,
68 (value != null ) ? Expression.Constant(value, value.GetType()) : null
69 );
70
71 LambdaExpression lambda = Expression.Lambda( typeof (Func < , > ).MakeGenericType(propertyType, typeof (Boolean)), equal, member.Expression as ParameterExpression);
72
73 query = whereMethod.Invoke( null , new Object[]{ query, lambda }) as IQueryable;
74
75 return (query);
76 }
77
78 public static IQueryable < T &> GroupBy < T &> ( this IQueryable < T &> query, String propertyName)
79 {
80 return (GroupBy(query as IQueryable, propertyName) as IQueryable < T &> );
81 }
82
83 public static IQueryable GroupBy( this IQueryable query, String propertyName)
84 {
85 Type propertyType = query.GetType().GetGenericArguments() [ 0 ];
86 PropertyInfo property = propertyType.GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public);
87 MethodInfo groupByMethod = typeof (Queryable).GetMethods(BindingFlags.Public | BindingFlags.Static).Where(m => m.Name == " GroupBy " && m.GetParameters().Length == 2 ).ToArray() [ 0 ].MakeGenericMethod(propertyType, property.PropertyType);
88
89 ParameterExpression parameter = Expression.Parameter
90 (
91 propertyType,
92 " m "
93 );
94
95 MemberExpression member = Expression.MakeMemberAccess
96 (
97 parameter,
98 propertyType.GetProperty(propertyName)
99 );
100
101 LambdaExpression lambda = Expression.Lambda
102 (
103 typeof (Func < , > ).MakeGenericType(propertyType, property.PropertyType),
104 member,
105 member.Expression as ParameterExpression
106 );
107
108 query = groupByMethod.Invoke( null , new Object [] { query, lambda }) as IQueryable;
109
110 return (query);
111 }
112
113 public static IQueryable < T &> OrderBy < T &> ( this IQueryable < T &> query, params String [] properties)
114 {
115 return (OrderBy(query as IQueryable, properties) as IQueryable < T &> );
116 }
117
118 public static IQueryable OrderBy( this IQueryable query, params String [] properties)
119 {
120 properties = (properties == null ) ? new String [ 0 ] : properties.Distinct().ToArray();
121
122 Type propertyType = query.GetType().GetGenericArguments()[ 0 ];
123 MethodInfo orderByMethod = typeof (Queryable).GetMethods(BindingFlags.Public | BindingFlags.Static).Where(m => m.Name == " OrderBy " ).ToArray() [ 0 ];
124 MethodInfo orderByDescMethod = typeof (Queryable).GetMethods(BindingFlags.Public | BindingFlags.Static).Where(m => m.Name == " OrderByDescending " ).ToArray() [ 0 ];
125 MethodInfo orderThenByMethod = typeof (Queryable).GetMethods(BindingFlags.Public | BindingFlags.Static).Where(m => m.Name == " ThenBy " ).ToArray() [ 0 ];
126 MethodInfo orderThenByDescMethod = typeof (Queryable).GetMethods(BindingFlags.Public | BindingFlags.Static).Where(m => m.Name == " ThenByDescending " ).ToArray() [ 0 ];
127 String [] parts = null ;
128 MethodInfo method = null ;
129 PropertyInfo property = null ;
130 MemberExpression member = null ;
131 LambdaExpression orderBy = null ;
132
133 for (Int32 i = 0 ; i < properties.Length; ++ i)
134 {
135 parts = properties[ i ].Split( ' ' );
136
137 property = propertyType.GetProperty(parts[ 0 ], BindingFlags.Instance | BindingFlags.Public);
138
139 if ((parts.Length == 1 ) || (parts [ 1 ].Equals( " asc " , StringComparison.OrdinalIgnoreCase) == true ))
140 {
141 if (i == 0 )
142 {
143 method = orderByMethod.MakeGenericMethod(propertyType, property.PropertyType);
144 }
145 else
146 {
147 method = orderThenByMethod.MakeGenericMethod(propertyType, property.PropertyType);
148 }
149 }
150 else if (parts[ 1 ].Equals( " desc " , StringComparison.OrdinalIgnoreCase) == true )
151 {
152 if (i == 0 )
153 {
154 method = orderByDescMethod.MakeGenericMethod(propertyType, property.PropertyType);
155 }
156 else
157 {
158 method = orderThenByDescMethod.MakeGenericMethod(propertyType, property.PropertyType);
159 }
160 }
161
162 member = Expression.MakeMemberAccess
163 (
164 Expression.Parameter(propertyType, " n " ),
165 property
166 );
167
168 orderBy = Expression.Lambda
169 (
170 member,
171 member.Expression as ParameterExpression
172 );
173
174 query = method.Invoke( null , new Object [] { query, orderBy }) as IQueryable;
175 }
176
177 return (query);
178 }
179
180 public static IQueryable Take( this IQueryable query, Int32 pageSize)
181 {
182 Type propertyType = query.GetType().GetGenericArguments() [ 0 ];
183 MethodInfo takeMethod = typeof (Queryable).GetMethod( " Take " , BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(propertyType);
184
185 query = takeMethod.Invoke( null , new Object [] { query, pageSize }) as IQueryable;
186
187 return (query);
188 }
189
190 public static IQueryable Skip( this IQueryable query, Int32 pageIndex)
191 {
192 Type propertyType = query.GetType().GetGenericArguments() [ 0 ];
193 MethodInfo skipMethod = typeof (Queryable).GetMethod( " Skip " , BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(propertyType);
194
195 query = skipMethod.Invoke( null , new Object [] { query, pageIndex }) as IQueryable;
196
197 return (query);
198 }
199 }
Here are some examples:
1
IQueryable q
=
...;
2 q = q.OrderBy( " NAME asc " , " BIRTHDAY desc " );
3 q = q.WhereEquals( " NAME " , " bla " );
4 q = q.GroupBy( " PROFILE ");
2 q = q.OrderBy( " NAME asc " , " BIRTHDAY desc " );
3 q = q.WhereEquals( " NAME " , " bla " );
4 q = q.GroupBy( " PROFILE ");
5 q = q.Take(10);