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 }