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);