Datei: NDODLL/Linq/VirtualTable.cs
Last Commit (16046d5)
1 | // |
2 | // Copyright (c) 2002-2016 Mirko Matytschak |
3 | // (www.netdataobjects.de) |
4 | // |
5 | // Author: Mirko Matytschak |
6 | // |
7 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated |
8 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation |
9 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the |
10 | // Software, and to permit persons to whom the Software is furnished to do so, subject to the following |
11 | // conditions: |
12 | |
13 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions |
14 | // of the Software. |
15 | // |
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED |
17 | // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
18 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF |
19 | // CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
20 | // DEALINGS IN THE SOFTWARE. |
21 | |
22 | |
23 | using System; |
24 | using System.Linq; |
25 | using System.Collections.Generic; |
26 | using System.Collections; |
27 | using NDO.Query; |
28 | using System.Linq.Expressions; |
29 | |
30 | namespace NDO.Linq |
31 | { |
32 | ····/// <summary> |
33 | ····/// This class represents a virtual table which allows for Linq queries against the NDO data store. |
34 | ····/// </summary> |
35 | ····/// <typeparam name="T">The type of the result element class.</typeparam> |
36 | ····public class VirtualTable<T> : IEnumerable<T> //where T: IPersistenceCapable |
37 | ····{ |
38 | ········PersistenceManager pm; |
39 | ········List<string> prefetches = new List<string>(); |
40 | ········int skip = -1; |
41 | ········int take = -1; |
42 | ········List<QueryOrder> orderings = new List<QueryOrder>(); |
43 | ········string queryString = String.Empty; |
44 | ········List<object> queryParameters = new List<object>(); |
45 | |
46 | ········/// <summary> |
47 | ········/// Constructs a virtual table object |
48 | ········/// </summary> |
49 | ········/// <param name="pm"></param> |
50 | ········public VirtualTable(PersistenceManager pm) |
51 | ········{ |
52 | ············this.pm = pm; |
53 | ········} |
54 | |
55 | ········/// <summary> |
56 | ········/// Implements the Linq select statement |
57 | ········/// </summary> |
58 | ········/// <typeparam name="S"></typeparam> |
59 | ········/// <param name="selector"></param> |
60 | ········/// <returns></returns> |
61 | ········public List<S> Select<S>(Func<T, S> selector) |
62 | ········{ |
63 | ············return this.ResultTable.Select( selector ).ToList(); |
64 | ········} |
65 | |
66 | ········/// <summary> |
67 | ········/// Implements the Linq orderby statement |
68 | ········/// </summary> |
69 | ········/// <typeparam name="K"></typeparam> |
70 | ········/// <param name="keySelector"></param> |
71 | ········/// <returns></returns> |
72 | ········public VirtualTable<T> OrderBy<K>(Expression<Func<T,K>> keySelector) |
73 | ········{ |
74 | ············ExpressionTreeTransformer transformer = |
75 | ················new ExpressionTreeTransformer((LambdaExpression)keySelector); |
76 | ············string field = transformer.Transform(); |
77 | ············this.orderings.Add(new Query.AscendingOrder(field)); |
78 | ············return this; |
79 | ········} |
80 | |
81 | ········/// <summary> |
82 | ········/// Implements the Linq orderby ... descending statement |
83 | ········/// </summary> |
84 | ········/// <typeparam name="K"></typeparam> |
85 | ········/// <param name="keySelector"></param> |
86 | ········/// <returns></returns> |
87 | ········public VirtualTable<T> OrderByDescending<K>(Expression<Func<T,K>> keySelector) |
88 | ········{ |
89 | ············ExpressionTreeTransformer transformer = |
90 | ················new ExpressionTreeTransformer((LambdaExpression)keySelector); |
91 | ············string field = transformer.Transform(); |
92 | ············this.orderings.Add(new Query.DescendingOrder(field)); |
93 | ············return this; |
94 | ········} |
95 | |
96 | ········/// <summary> |
97 | ········/// Implements the Linq orderby statement |
98 | ········/// </summary> |
99 | ········/// <typeparam name="K"></typeparam> |
100 | ········/// <param name="keySelector"></param> |
101 | ········/// <returns></returns> |
102 | ········public VirtualTable<T> ThenBy<K>(Expression<Func<T,K>> keySelector) |
103 | ········{ |
104 | ············return OrderBy<K>(keySelector); |
105 | ········} |
106 | |
107 | ········/// <summary> |
108 | ········/// Implements the Linq orderby statement |
109 | ········/// </summary> |
110 | ········/// <typeparam name="K"></typeparam> |
111 | ········/// <param name="keySelector"></param> |
112 | ········/// <returns></returns> |
113 | ········public VirtualTable<T> ThenByDescending<K>(Expression<Func<T,K>> keySelector) |
114 | ········{ |
115 | ············return OrderByDescending<K>(keySelector); |
116 | ········} |
117 | |
118 | ········/// <summary> |
119 | ········/// Implements the Linq where clause |
120 | ········/// </summary> |
121 | ········/// <param name="expr"></param> |
122 | ········/// <returns></returns> |
123 | ········public VirtualTable<T>Where(Expression<Func<T,bool>>expr) |
124 | ········{ |
125 | ············// Transform the expression to NDOql |
126 | ············ExpressionTreeTransformer transformer = new ExpressionTreeTransformer((LambdaExpression)expr); |
127 | ············this.queryString = transformer.Transform(); |
128 | |
129 | ············this.queryParameters.Clear(); |
130 | ············// Add the parameters collected by the transformer |
131 | ············foreach(object o in transformer.Parameters) |
132 | ················this.queryParameters.Add(o); |
133 | |
134 | ············return this; |
135 | ········} |
136 | |
137 | ········/// <summary> |
138 | ········/// Allows to reuse a VirtualTable with different parameters. |
139 | ········/// Parameters must have the same order, as they appear in the Linq query. |
140 | ········/// </summary> |
141 | ········/// <param name="newParameters"></param> |
142 | ········public void ReplaceParameters(IEnumerable<object> newParameters) |
143 | ········{ |
144 | ············this.queryParameters.Clear(); |
145 | ············foreach (var p in newParameters) |
146 | ············{ |
147 | ················this.queryParameters.Add( p ); |
148 | ············} |
149 | ········} |
150 | |
151 | ········/// <summary> |
152 | ········/// Executes the COUNT aggregate query for the given virtual table. |
153 | ········/// </summary> |
154 | ········public int Count |
155 | ········{ |
156 | ············get |
157 | ············{ |
158 | ················var ndoQuery = Ndoquery; |
159 | ················return (int)(decimal)ndoQuery.ExecuteAggregate( "*", AggregateType.Count ); |
160 | ············} |
161 | ········} |
162 | |
163 | ········/// <summary> |
164 | ········/// Executes the MAX aggregate query for the given virtual table. |
165 | ········/// </summary> |
166 | ········/// <typeparam name="TP"></typeparam> |
167 | ········/// <param name="fieldSelector"></param> |
168 | ········/// <returns></returns> |
169 | ········public TP Max<TP>( Expression<Func<T, TP>> fieldSelector ) |
170 | ········{ |
171 | ············return ExecuteAggregate(fieldSelector, AggregateType.Max ); |
172 | ········} |
173 | |
174 | ········/// <summary> |
175 | ········/// Executes the MAX aggregate query for the given virtual table. |
176 | ········/// </summary> |
177 | ········/// <typeparam name="TP"></typeparam> |
178 | ········/// <param name="fieldSelector"></param> |
179 | ········/// <returns></returns> |
180 | ········public TP Min<TP>( Expression<Func<T, TP>> fieldSelector ) |
181 | ········{ |
182 | ············return ExecuteAggregate( fieldSelector, AggregateType.Min ); |
183 | ········} |
184 | |
185 | ········/// <summary> |
186 | ········/// Executes the MAX aggregate query for the given virtual table. |
187 | ········/// </summary> |
188 | ········/// <typeparam name="TP"></typeparam> |
189 | ········/// <param name="fieldSelector"></param> |
190 | ········/// <returns></returns> |
191 | ········public TP StandardDeviation<TP>( Expression<Func<T, TP>> fieldSelector ) |
192 | ········{ |
193 | ············return ExecuteAggregate( fieldSelector, AggregateType.StDev ); |
194 | ········} |
195 | |
196 | ········/// <summary> |
197 | ········/// Executes the MAX aggregate query for the given virtual table. |
198 | ········/// </summary> |
199 | ········/// <typeparam name="TP"></typeparam> |
200 | ········/// <param name="fieldSelector"></param> |
201 | ········/// <returns></returns> |
202 | ········public TP Average<TP>( Expression<Func<T, TP>> fieldSelector ) |
203 | ········{ |
204 | ············return ExecuteAggregate( fieldSelector, AggregateType.Avg ); |
205 | ········} |
206 | |
207 | ········/// <summary> |
208 | ········/// Executes the SUM aggregate query for the given virtual table. |
209 | ········/// </summary> |
210 | ········/// <typeparam name="TP"></typeparam> |
211 | ········/// <param name="fieldSelector"></param> |
212 | ········/// <returns></returns> |
213 | ········public TP Sum<TP>( Expression<Func<T, TP>> fieldSelector ) |
214 | ········{ |
215 | ············return ExecuteAggregate( fieldSelector, AggregateType.Sum ); |
216 | ········} |
217 | |
218 | ········/// <summary> |
219 | ········/// Executes the VAR aggregate query for the given virtual table. |
220 | ········/// </summary> |
221 | ········/// <typeparam name="TP"></typeparam> |
222 | ········/// <param name="fieldSelector"></param> |
223 | ········/// <returns></returns> |
224 | ········public TP Variance<TP>( Expression<Func<T, TP>> fieldSelector ) |
225 | ········{ |
226 | ············return ExecuteAggregate( fieldSelector, AggregateType.Var ); |
227 | ········} |
228 | |
229 | ········string GetField<TP>( Expression<Func<T, TP>> fieldSelector ) |
230 | ········{ |
231 | ············ExpressionTreeTransformer transformer = |
232 | ················new ExpressionTreeTransformer( fieldSelector ); |
233 | ············return transformer.Transform(); |
234 | ········} |
235 | |
236 | ········/// <summary> |
237 | ········/// /// Executes the aggregate query for the given virtual table. |
238 | ········/// </summary> |
239 | ········/// <typeparam name="TP"></typeparam> |
240 | ········/// <param name="fieldSelector"></param> |
241 | ········/// <param name="aggregateType"></param> |
242 | ········/// <returns></returns> |
243 | ········TP ExecuteAggregate<TP>( Expression<Func<T, TP>> fieldSelector, AggregateType aggregateType ) |
244 | ········{ |
245 | ············return (TP)Ndoquery.ExecuteAggregate( GetField(fieldSelector), aggregateType ); |
246 | ········} |
247 | |
248 | ········/// <summary> |
249 | ········/// Executes the Query and returns the result table |
250 | ········/// </summary> |
251 | ········public List<T> ResultTable |
252 | ········{ |
253 | ············get |
254 | ············{ |
255 | ················return Ndoquery.Execute(); |
256 | ············} |
257 | ········} |
258 | |
259 | ········/// <summary> |
260 | ········/// Returns the prefetches. |
261 | ········/// </summary> |
262 | ········public IEnumerable<string> Prefetches |
263 | ········{ |
264 | ············get { return this.prefetches; } |
265 | ········} |
266 | |
267 | ········/// <summary> |
268 | ········/// Add an expression which represents a relation. The query will try to fetch these related objects together with the main resultset. |
269 | ········/// </summary> |
270 | ········/// <typeparam name="TP">The type of the property - will be automatically determined by the compiler.</typeparam> |
271 | ········/// <param name="expr"></param> |
272 | ········public void AddPrefetch<TP>( Expression<Func<T, TP>> expr ) |
273 | ········{ |
274 | ············ExpressionTreeTransformer transformer = |
275 | ················new ExpressionTreeTransformer( (LambdaExpression)expr ); |
276 | ············string field = transformer.Transform(); |
277 | ············this.prefetches.Add( field ); |
278 | ········} |
279 | |
280 | ········/// <summary> |
281 | ········/// Gets the Query String of the generated query. |
282 | ········/// </summary> |
283 | ········public string QueryString |
284 | ········{ |
285 | ············get |
286 | ············{ |
287 | ················return Ndoquery.GeneratedQuery; |
288 | ············} |
289 | ········} |
290 | |
291 | ········NDOQuery<T> CreateNDOQuery() |
292 | ········{ |
293 | ············var ndoquery = new NDOQuery<T>( pm, this.queryString ); |
294 | ············if (this.take > -1) |
295 | ················ndoquery.Take = take; |
296 | ············if (this.skip > -1) |
297 | ················ndoquery.Skip = skip; |
298 | ············ndoquery.Prefetches = this.prefetches; |
299 | ············foreach (var p in this.queryParameters) |
300 | ············{ |
301 | ················ndoquery.Parameters.Add( p ); |
302 | ············} |
303 | ············ndoquery.Orderings = this.orderings; |
304 | ············return ndoquery; |
305 | ········} |
306 | |
307 | ········private NDOQuery<T> Ndoquery |
308 | ········{ |
309 | ············get |
310 | ············{ |
311 | ················return CreateNDOQuery(); |
312 | ············} |
313 | ········} |
314 | |
315 | ········/// <summary> |
316 | ········/// Supports getting a paged view with Linq |
317 | ········/// </summary> |
318 | ········/// <param name="skip"></param> |
319 | ········/// <param name="take"></param> |
320 | ········/// <returns></returns> |
321 | ········public VirtualTable<T> PagedView(int skip, int take) |
322 | ········{ |
323 | ············this.skip = skip; |
324 | ············this.take = take; |
325 | ············return this; |
326 | ········} |
327 | |
328 | ········/// <summary> |
329 | ········/// Supports Take and Skip |
330 | ········/// </summary> |
331 | ········/// <param name="take"></param> |
332 | ········/// <returns></returns> |
333 | ········public VirtualTable<T> Take( int take ) |
334 | ········{ |
335 | ············this.take = take; |
336 | ············return this; |
337 | ········} |
338 | |
339 | ········/// <summary> |
340 | ········/// Supports Take and Skip |
341 | ········/// </summary> |
342 | ········/// <param name="skip"></param> |
343 | ········/// <returns></returns> |
344 | ········public VirtualTable<T> Skip( int skip ) |
345 | ········{ |
346 | ············this.skip = skip; |
347 | ············return this; |
348 | ········} |
349 | |
350 | ········/// <summary> |
351 | ········/// Converts the VirtualTable to a List. |
352 | ········/// </summary> |
353 | ········/// <remarks>This operator makes sure that the results of the Linq query are usable as List classes.</remarks> |
354 | ········/// <param name="table"></param> |
355 | ········/// <returns></returns> |
356 | ········public static implicit operator List<T>(VirtualTable<T> table) |
357 | ········{ |
358 | ············return table.ResultTable; |
359 | ········} |
360 | |
361 | ········/// <summary> |
362 | ········/// Gets a single object with the query |
363 | ········/// </summary> |
364 | ········/// <returns></returns> |
365 | ········public T FirstOrDefault() |
366 | ········{ |
367 | ············return Ndoquery.ExecuteSingle( false ); |
368 | ········} |
369 | |
370 | ········/// <summary> |
371 | ········/// Gets a single object with the query |
372 | ········/// </summary> |
373 | ········/// <returns></returns> |
374 | ········public T SingleOrDefault() |
375 | ········{ |
376 | ············return FirstOrDefault(); |
377 | ········} |
378 | |
379 | ········/// <summary> |
380 | ········/// Gets a single object with the query |
381 | ········/// </summary> |
382 | ········/// <returns></returns> |
383 | ········/// <remarks>Throws a NDOException, if the query fetches an empty result set.</remarks> |
384 | ········public T First() |
385 | ········{ |
386 | ············return Ndoquery.ExecuteSingle( true ); |
387 | ········} |
388 | |
389 | ········/// <summary> |
390 | ········/// Gets a single object with the query |
391 | ········/// </summary> |
392 | ········/// <returns></returns> |
393 | ········/// <remarks>Throws a NDOException, if the query fetches an empty result set.</remarks> |
394 | ········public T Single() |
395 | ········{ |
396 | ············return Ndoquery.ExecuteSingle( true ); |
397 | ········} |
398 | |
399 | ········/// <summary> |
400 | ········/// Gets an Enumerable for iterating over a VirtualTable with foreach |
401 | ········/// </summary> |
402 | ········/// <returns></returns> |
403 | ········public IEnumerator<T> GetEnumerator() |
404 | ········{ |
405 | ············return ResultTable.GetEnumerator(); |
406 | ········} |
407 | |
408 | ········/// <summary> |
409 | ········/// Gets an untyped Enumerable for iterating over a VirtualTable with foreach |
410 | ········/// </summary> |
411 | ········/// <returns></returns> |
412 | ········IEnumerator IEnumerable.GetEnumerator() |
413 | ········{ |
414 | ············return ResultTable.GetEnumerator(); |
415 | ········} |
416 | ····} |
417 | } |
New Commit (43dcc14)
1 | // |
2 | // Copyright (c) 2002-2016 Mirko Matytschak |
3 | // (www.netdataobjects.de) |
4 | // |
5 | // Author: Mirko Matytschak |
6 | // |
7 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated |
8 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation |
9 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the |
10 | // Software, and to permit persons to whom the Software is furnished to do so, subject to the following |
11 | // conditions: |
12 | |
13 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions |
14 | // of the Software. |
15 | // |
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED |
17 | // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
18 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF |
19 | // CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
20 | // DEALINGS IN THE SOFTWARE. |
21 | |
22 | |
23 | using System; |
24 | using System.Linq; |
25 | using System.Collections.Generic; |
26 | using System.Collections; |
27 | using NDO.Query; |
28 | using System.Linq.Expressions; |
29 | |
30 | namespace NDO.Linq |
31 | { |
32 | ····/// <summary> |
33 | ····/// This class represents a virtual table which allows for Linq queries against the NDO data store. |
34 | ····/// </summary> |
35 | ····/// <typeparam name="T">The type of the result element class.</typeparam> |
36 | ····public class VirtualTable<T> : IEnumerable<T> //where T: IPersistenceCapable |
37 | ····{ |
38 | ········PersistenceManager pm; |
39 | ········List<string> prefetches = new List<string>(); |
40 | ········int skip = -1; |
41 | ········int take = -1; |
42 | ········List<QueryOrder> orderings = new List<QueryOrder>(); |
43 | ········string queryString = String.Empty; |
44 | ········List<object> queryParameters = new List<object>(); |
45 | |
46 | ········/// <summary> |
47 | ········/// Constructs a virtual table object |
48 | ········/// </summary> |
49 | ········/// <param name="pm"></param> |
50 | ········public VirtualTable(PersistenceManager pm) |
51 | ········{ |
52 | ············this.pm = pm; |
53 | ········} |
54 | |
55 | ········/// <summary> |
56 | ········/// Implements the Linq select statement |
57 | ········/// </summary> |
58 | ········/// <typeparam name="S"></typeparam> |
59 | ········/// <param name="selector"></param> |
60 | ········/// <returns></returns> |
61 | ········public List<S> Select<S>(Func<T, S> selector) |
62 | ········{ |
63 | ············return this.ResultTable.Select( selector ).ToList(); |
64 | ········} |
65 | |
66 | ········/// <summary> |
67 | ········/// Implements the Linq orderby statement |
68 | ········/// </summary> |
69 | ········/// <typeparam name="K"></typeparam> |
70 | ········/// <param name="keySelector"></param> |
71 | ········/// <returns></returns> |
72 | ········public VirtualTable<T> OrderBy<K>(Expression<Func<T,K>> keySelector) |
73 | ········{ |
74 | ············ExpressionTreeTransformer transformer = |
75 | ················new ExpressionTreeTransformer((LambdaExpression)keySelector); |
76 | ············string field = transformer.Transform(); |
77 | ············this.orderings.Add(new Query.AscendingOrder(field)); |
78 | ············return this; |
79 | ········} |
80 | |
81 | ········/// <summary> |
82 | ········/// Implements the Linq orderby ... descending statement |
83 | ········/// </summary> |
84 | ········/// <typeparam name="K"></typeparam> |
85 | ········/// <param name="keySelector"></param> |
86 | ········/// <returns></returns> |
87 | ········public VirtualTable<T> OrderByDescending<K>(Expression<Func<T,K>> keySelector) |
88 | ········{ |
89 | ············ExpressionTreeTransformer transformer = |
90 | ················new ExpressionTreeTransformer((LambdaExpression)keySelector); |
91 | ············string field = transformer.Transform(); |
92 | ············this.orderings.Add(new Query.DescendingOrder(field)); |
93 | ············return this; |
94 | ········} |
95 | |
96 | ········/// <summary> |
97 | ········/// Implements the Linq orderby statement |
98 | ········/// </summary> |
99 | ········/// <typeparam name="K"></typeparam> |
100 | ········/// <param name="keySelector"></param> |
101 | ········/// <returns></returns> |
102 | ········public VirtualTable<T> ThenBy<K>(Expression<Func<T,K>> keySelector) |
103 | ········{ |
104 | ············return OrderBy<K>(keySelector); |
105 | ········} |
106 | |
107 | ········/// <summary> |
108 | ········/// Implements the Linq orderby statement |
109 | ········/// </summary> |
110 | ········/// <typeparam name="K"></typeparam> |
111 | ········/// <param name="keySelector"></param> |
112 | ········/// <returns></returns> |
113 | ········public VirtualTable<T> ThenByDescending<K>(Expression<Func<T,K>> keySelector) |
114 | ········{ |
115 | ············return OrderByDescending<K>(keySelector); |
116 | ········} |
117 | |
118 | ········/// <summary> |
119 | ········/// Implements the Linq where clause |
120 | ········/// </summary> |
121 | ········/// <param name="expr"></param> |
122 | ········/// <returns></returns> |
123 | ········public VirtualTable<T>Where(Expression<Func<T,bool>>expr) |
124 | ········{ |
125 | ············// Transform the expression to NDOql |
126 | ············ExpressionTreeTransformer transformer = new ExpressionTreeTransformer((LambdaExpression)expr); |
127 | ············this.queryString = transformer.Transform(); |
128 | |
129 | ············this.queryParameters.Clear(); |
130 | ············// Add the parameters collected by the transformer |
131 | ············foreach(object o in transformer.Parameters) |
132 | ················this.queryParameters.Add(o); |
133 | |
134 | ············return this; |
135 | ········} |
136 | |
137 | ········/// <summary> |
138 | ········/// Allows to reuse a VirtualTable with different parameters. |
139 | ········/// Parameters must have the same order, as they appear in the Linq query. |
140 | ········/// </summary> |
141 | ········/// <param name="newParameters"></param> |
142 | ········public void ReplaceParameters(IEnumerable<object> newParameters) |
143 | ········{ |
144 | ············this.queryParameters.Clear(); |
145 | ············foreach (var p in newParameters) |
146 | ············{ |
147 | ················this.queryParameters.Add( p ); |
148 | ············} |
149 | ········} |
150 | |
151 | ········/// <summary> |
152 | ········/// Executes the COUNT aggregate query for the given virtual table. |
153 | ········/// </summary> |
154 | ········public int Count |
155 | ········{ |
156 | ············get |
157 | ············{ |
158 | ················var ndoQuery = Ndoquery; |
159 | ················return (int)(decimal)ndoQuery.ExecuteAggregate( "*", AggregateType.Count ); |
160 | ············} |
161 | ········} |
162 | |
163 | ········/// <summary> |
164 | ········/// Executes the MAX aggregate query for the given virtual table. |
165 | ········/// </summary> |
166 | ········/// <typeparam name="TP"></typeparam> |
167 | ········/// <param name="fieldSelector"></param> |
168 | ········/// <returns></returns> |
169 | ········public TP Max<TP>( Expression<Func<T, TP>> fieldSelector ) |
170 | ········{ |
171 | ············return ExecuteAggregate(fieldSelector, AggregateType.Max ); |
172 | ········} |
173 | |
174 | ········/// <summary> |
175 | ········/// Executes the MAX aggregate query for the given virtual table. |
176 | ········/// </summary> |
177 | ········/// <typeparam name="TP"></typeparam> |
178 | ········/// <param name="fieldSelector"></param> |
179 | ········/// <returns></returns> |
180 | ········public TP Min<TP>( Expression<Func<T, TP>> fieldSelector ) |
181 | ········{ |
182 | ············return ExecuteAggregate( fieldSelector, AggregateType.Min ); |
183 | ········} |
184 | |
185 | ········/// <summary> |
186 | ········/// Executes the MAX aggregate query for the given virtual table. |
187 | ········/// </summary> |
188 | ········/// <typeparam name="TP"></typeparam> |
189 | ········/// <param name="fieldSelector"></param> |
190 | ········/// <returns></returns> |
191 | ········public TP StandardDeviation<TP>( Expression<Func<T, TP>> fieldSelector ) |
192 | ········{ |
193 | ············return ExecuteAggregate( fieldSelector, AggregateType.StDev ); |
194 | ········} |
195 | |
196 | ········/// <summary> |
197 | ········/// Executes the MAX aggregate query for the given virtual table. |
198 | ········/// </summary> |
199 | ········/// <typeparam name="TP"></typeparam> |
200 | ········/// <param name="fieldSelector"></param> |
201 | ········/// <returns></returns> |
202 | ········public TP Average<TP>( Expression<Func<T, TP>> fieldSelector ) |
203 | ········{ |
204 | ············return ExecuteAggregate( fieldSelector, AggregateType.Avg ); |
205 | ········} |
206 | |
207 | ········/// <summary> |
208 | ········/// Executes the SUM aggregate query for the given virtual table. |
209 | ········/// </summary> |
210 | ········/// <typeparam name="TP"></typeparam> |
211 | ········/// <param name="fieldSelector"></param> |
212 | ········/// <returns></returns> |
213 | ········public TP Sum<TP>( Expression<Func<T, TP>> fieldSelector ) |
214 | ········{ |
215 | ············return ExecuteAggregate( fieldSelector, AggregateType.Sum ); |
216 | ········} |
217 | |
218 | ········/// <summary> |
219 | ········/// Executes the VAR aggregate query for the given virtual table. |
220 | ········/// </summary> |
221 | ········/// <typeparam name="TP"></typeparam> |
222 | ········/// <param name="fieldSelector"></param> |
223 | ········/// <returns></returns> |
224 | ········public TP Variance<TP>( Expression<Func<T, TP>> fieldSelector ) |
225 | ········{ |
226 | ············return ExecuteAggregate( fieldSelector, AggregateType.Var ); |
227 | ········} |
228 | |
229 | ········string GetField<TP>( Expression<Func<T, TP>> fieldSelector ) |
230 | ········{ |
231 | ············ExpressionTreeTransformer transformer = |
232 | ················new ExpressionTreeTransformer( fieldSelector ); |
233 | ············return transformer.Transform(); |
234 | ········} |
235 | |
236 | ········/// <summary> |
237 | ········/// /// Executes the aggregate query for the given virtual table. |
238 | ········/// </summary> |
239 | ········/// <typeparam name="TP"></typeparam> |
240 | ········/// <param name="fieldSelector"></param> |
241 | ········/// <param name="aggregateType"></param> |
242 | ········/// <returns></returns> |
243 | ········TP ExecuteAggregate<TP>( Expression<Func<T, TP>> fieldSelector, AggregateType aggregateType ) |
244 | ········{ |
245 | ············return (TP)Ndoquery.ExecuteAggregate( GetField(fieldSelector), aggregateType ); |
246 | ········} |
247 | |
248 | ········/// <summary> |
249 | ········/// Executes the Query and returns the result table |
250 | ········/// </summary> |
251 | ········public List<T> ResultTable |
252 | ········{ |
253 | ············get |
254 | ············{ |
255 | ················return Ndoquery.Execute(); |
256 | ············} |
257 | ········} |
258 | |
259 | ········/// <summary> |
260 | ········/// Returns the prefetches. |
261 | ········/// </summary> |
262 | ········public IEnumerable<string> Prefetches |
263 | ········{ |
264 | ············get { return this.prefetches; } |
265 | ········} |
266 | |
267 | ········/// <summary> |
268 | ········/// Add an expression which represents a relation. The query will try to fetch these related objects together with the main resultset. |
269 | ········/// </summary> |
270 | ········/// <typeparam name="TP">The type of the property - will be automatically determined by the compiler.</typeparam> |
271 | ········/// <param name="expr"></param> |
272 | ········public void AddPrefetch<TP>( Expression<Func<T, TP>> expr ) |
273 | ········{ |
274 | ············ExpressionTreeTransformer transformer = |
275 | ················new ExpressionTreeTransformer( (LambdaExpression)expr ); |
276 | ············string field = transformer.Transform(); |
277 | ············this.prefetches.Add( field ); |
278 | ········} |
279 | |
280 | ········/// <summary> |
281 | ········/// Gets the Query String of the generated query. |
282 | ········/// </summary> |
283 | ········public string QueryString |
284 | ········{ |
285 | ············get |
286 | ············{ |
287 | ················return Ndoquery.GeneratedQuery; |
288 | ············} |
289 | ········} |
290 | |
291 | ········NDOQuery<T> CreateNDOQuery() |
292 | ········{ |
293 | ············var ndoquery = new NDOQuery<T>( pm, this.queryString ); |
294 | ············if (this.take > -1) |
295 | ················ndoquery.Take = take; |
296 | ············if (this.skip > -1) |
297 | ················ndoquery.Skip = skip; |
298 | ············ndoquery.Prefetches = this.prefetches; |
299 | ············foreach (var p in this.queryParameters) |
300 | ············{ |
301 | ················ndoquery.Parameters.Add( p ); |
302 | ············} |
303 | ············ndoquery.Orderings = this.orderings; |
304 | ············return ndoquery; |
305 | ········} |
306 | |
307 | ········private NDOQuery<T> Ndoquery |
308 | ········{ |
309 | ············get |
310 | ············{ |
311 | ················return CreateNDOQuery(); |
312 | ············} |
313 | ········} |
314 | |
315 | ········/// <summary> |
316 | ········/// Deletes records directly without caring for composite relations. |
317 | ········/// </summary> |
318 | ········/// <remarks>Only use this method if your class does not use composite relations and you are sure that this will not be the case in the future either. If you are unsure about this, you better use PersistenceManager.Delete ().</remarks> |
319 | ········public void DeleteDirectly() |
320 | ········{ |
321 | ············Ndoquery.DeleteDirectly(); |
322 | ········} |
323 | |
324 | ········/// <summary> |
325 | ········/// Supports getting a paged view with Linq |
326 | ········/// </summary> |
327 | ········/// <param name="skip"></param> |
328 | ········/// <param name="take"></param> |
329 | ········/// <returns></returns> |
330 | ········public VirtualTable<T> PagedView(int skip, int take) |
331 | ········{ |
332 | ············this.skip = skip; |
333 | ············this.take = take; |
334 | ············return this; |
335 | ········} |
336 | |
337 | ········/// <summary> |
338 | ········/// Supports Take and Skip |
339 | ········/// </summary> |
340 | ········/// <param name="take"></param> |
341 | ········/// <returns></returns> |
342 | ········public VirtualTable<T> Take( int take ) |
343 | ········{ |
344 | ············this.take = take; |
345 | ············return this; |
346 | ········} |
347 | |
348 | ········/// <summary> |
349 | ········/// Supports Take and Skip |
350 | ········/// </summary> |
351 | ········/// <param name="skip"></param> |
352 | ········/// <returns></returns> |
353 | ········public VirtualTable<T> Skip( int skip ) |
354 | ········{ |
355 | ············this.skip = skip; |
356 | ············return this; |
357 | ········} |
358 | |
359 | ········/// <summary> |
360 | ········/// Converts the VirtualTable to a List. |
361 | ········/// </summary> |
362 | ········/// <remarks>This operator makes sure that the results of the Linq query are usable as List classes.</remarks> |
363 | ········/// <param name="table"></param> |
364 | ········/// <returns></returns> |
365 | ········public static implicit operator List<T>(VirtualTable<T> table) |
366 | ········{ |
367 | ············return table.ResultTable; |
368 | ········} |
369 | |
370 | ········/// <summary> |
371 | ········/// Gets a single object with the query |
372 | ········/// </summary> |
373 | ········/// <returns></returns> |
374 | ········public T FirstOrDefault() |
375 | ········{ |
376 | ············return Ndoquery.ExecuteSingle( false ); |
377 | ········} |
378 | |
379 | ········/// <summary> |
380 | ········/// Gets a single object with the query |
381 | ········/// </summary> |
382 | ········/// <returns></returns> |
383 | ········public T SingleOrDefault() |
384 | ········{ |
385 | ············return FirstOrDefault(); |
386 | ········} |
387 | |
388 | ········/// <summary> |
389 | ········/// Gets a single object with the query |
390 | ········/// </summary> |
391 | ········/// <returns></returns> |
392 | ········/// <remarks>Throws a NDOException, if the query fetches an empty result set.</remarks> |
393 | ········public T First() |
394 | ········{ |
395 | ············return Ndoquery.ExecuteSingle( true ); |
396 | ········} |
397 | |
398 | ········/// <summary> |
399 | ········/// Gets a single object with the query |
400 | ········/// </summary> |
401 | ········/// <returns></returns> |
402 | ········/// <remarks>Throws a NDOException, if the query fetches an empty result set.</remarks> |
403 | ········public T Single() |
404 | ········{ |
405 | ············return Ndoquery.ExecuteSingle( true ); |
406 | ········} |
407 | |
408 | ········/// <summary> |
409 | ········/// Gets an Enumerable for iterating over a VirtualTable with foreach |
410 | ········/// </summary> |
411 | ········/// <returns></returns> |
412 | ········public IEnumerator<T> GetEnumerator() |
413 | ········{ |
414 | ············return ResultTable.GetEnumerator(); |
415 | ········} |
416 | |
417 | ········/// <summary> |
418 | ········/// Gets an untyped Enumerable for iterating over a VirtualTable with foreach |
419 | ········/// </summary> |
420 | ········/// <returns></returns> |
421 | ········IEnumerator IEnumerable.GetEnumerator() |
422 | ········{ |
423 | ············return ResultTable.GetEnumerator(); |
424 | ········} |
425 | ····} |
426 | } |