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(nullnew 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(nullnew 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(nullnew 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(nullnew 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(nullnew 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(nullnew Object [] { query, pageIndex }) as IQueryable;
196 
197         return (query);
198     }

199  }

Here are some examples:


1 IQueryable q = ...;
2 = q.OrderBy("NAME asc""BIRTHDAY desc");
3 = q.WhereEquals("NAME""bla");
4 = q.GroupBy("PROFILE");

5  = q.Take(10);

 

 

 

posted on 2011-04-10 17:50  尚書  阅读(1188)  评论(0编辑  收藏  举报