comparison Source/Data/Linq/LinqExtensions.cs @ 0:f990fcb411a9

Копия текущей версии из github
author cin
date Thu, 27 Mar 2014 21:46:09 +0400
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:f990fcb411a9
1 using System;
2 using System.Linq;
3 using System.Linq.Expressions;
4 using System.Reflection;
5
6 using JetBrains.Annotations;
7
8 namespace BLToolkit.Data.Linq
9 {
10 public static class LinqExtensions
11 {
12 #region Table Helpers
13
14 static public Table<T> TableName<T>([NotNull] this Table<T> table, [NotNull] string name)
15 {
16 if (table == null) throw new ArgumentNullException("table");
17 if (name == null) throw new ArgumentNullException("name");
18
19 table.Expression = Expression.Call(
20 null,
21 ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T) }),
22 new[] { table.Expression, Expression.Constant(name) });
23
24 return table;
25 }
26
27 static public Table<T> DatabaseName<T>([NotNull] this Table<T> table, [NotNull] string name)
28 {
29 if (table == null) throw new ArgumentNullException("table");
30 if (name == null) throw new ArgumentNullException("name");
31
32 table.Expression = Expression.Call(
33 null,
34 ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T) }),
35 new[] { table.Expression, Expression.Constant(name) });
36
37 return table;
38 }
39
40 static public Table<T> OwnerName<T>([NotNull] this Table<T> table, [NotNull] string name)
41 {
42 if (table == null) throw new ArgumentNullException("table");
43 if (name == null) throw new ArgumentNullException("name");
44
45 table.Expression = Expression.Call(
46 null,
47 ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T) }),
48 new[] { table.Expression, Expression.Constant(name) });
49
50 return table;
51 }
52
53 #endregion
54
55 #region Scalar Select
56
57 static public T Select<T>([NotNull] this IDataContext dataContext, [NotNull, InstantHandle] Expression<Func<T>> selector)
58 {
59 if (dataContext == null) throw new ArgumentNullException("dataContext");
60 if (selector == null) throw new ArgumentNullException("selector");
61
62 var q = new Table<T>(dataContext, selector);
63
64 foreach (var item in q)
65 return item;
66
67 throw new InvalidOperationException();
68 }
69
70 #endregion
71
72 #region Delete
73
74 public static int Delete<T>([NotNull] this IQueryable<T> source)
75 {
76 if (source == null) throw new ArgumentNullException("source");
77
78 return source.Provider.Execute<int>(
79 Expression.Call(
80 null,
81 ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T) }),
82 new[] { source.Expression }));
83 }
84
85 public static int Delete<T>(
86 [NotNull, InstantHandle] this IQueryable<T> source,
87 [NotNull, InstantHandle] Expression<Func<T,bool>> predicate)
88 {
89 if (source == null) throw new ArgumentNullException("source");
90 if (predicate == null) throw new ArgumentNullException("predicate");
91
92 return source.Provider.Execute<int>(
93 Expression.Call(
94 null,
95 ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T) }),
96 new[] { source.Expression, Expression.Quote(predicate) }));
97 }
98
99 #endregion
100
101 #region Update
102
103 public static int Update<TSource,TTarget>(
104 [NotNull] this IQueryable<TSource> source,
105 [NotNull] Table<TTarget> target,
106 [NotNull, InstantHandle] Expression<Func<TSource,TTarget>> setter)
107 {
108 if (source == null) throw new ArgumentNullException("source");
109 if (target == null) throw new ArgumentNullException("target");
110 if (setter == null) throw new ArgumentNullException("setter");
111
112 return source.Provider.Execute<int>(
113 Expression.Call(
114 null,
115 ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(TSource), typeof(TTarget) }),
116 new[] { source.Expression, ((IQueryable<TTarget>)target).Expression, Expression.Quote(setter) }));
117 }
118
119 public static int Update<T>(
120 [NotNull] this IQueryable<T> source,
121 [NotNull, InstantHandle] Expression<Func<T,T>> setter)
122 {
123 if (source == null) throw new ArgumentNullException("source");
124 if (setter == null) throw new ArgumentNullException("setter");
125
126 return source.Provider.Execute<int>(
127 Expression.Call(
128 null,
129 ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T) }),
130 new[] { source.Expression, Expression.Quote(setter) }));
131 }
132
133 public static int Update<T>(
134 [NotNull] this IQueryable<T> source,
135 [NotNull, InstantHandle] Expression<Func<T,bool>> predicate,
136 [NotNull, InstantHandle] Expression<Func<T,T>> setter)
137 {
138 if (source == null) throw new ArgumentNullException("source");
139 if (predicate == null) throw new ArgumentNullException("predicate");
140 if (setter == null) throw new ArgumentNullException("setter");
141
142 return source.Provider.Execute<int>(
143 Expression.Call(
144 null,
145 ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T) }),
146 new[] { source.Expression, Expression.Quote(predicate), Expression.Quote(setter) }));
147 }
148
149 public static int Update<T>([NotNull] this IUpdatable<T> source)
150 {
151 if (source == null) throw new ArgumentNullException("source");
152
153 var query = ((Updatable<T>)source).Query;
154
155 return query.Provider.Execute<int>(
156 Expression.Call(
157 null,
158 ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T) }),
159 new[] { query.Expression }));
160 }
161
162 class Updatable<T> : IUpdatable<T>
163 {
164 public IQueryable<T> Query;
165 }
166
167 public static IUpdatable<T> AsUpdatable<T>([NotNull] this IQueryable<T> source)
168 {
169 if (source == null) throw new ArgumentNullException("source");
170
171 var query = source.Provider.CreateQuery<T>(
172 Expression.Call(
173 null,
174 ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T) }),
175 new[] { source.Expression }));
176
177 return new Updatable<T> { Query = query };
178 }
179
180 public static IUpdatable<T> Set<T,TV>(
181 [NotNull] this IQueryable<T> source,
182 [NotNull, InstantHandle] Expression<Func<T,TV>> extract,
183 [NotNull, InstantHandle] Expression<Func<T,TV>> update)
184 {
185 if (source == null) throw new ArgumentNullException("source");
186 if (extract == null) throw new ArgumentNullException("extract");
187 if (update == null) throw new ArgumentNullException("update");
188
189 var query = source.Provider.CreateQuery<T>(
190 Expression.Call(
191 null,
192 ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T), typeof(TV) }),
193 new[] { source.Expression, Expression.Quote(extract), Expression.Quote(update) }));
194
195 return new Updatable<T> { Query = query };
196 }
197
198 public static IUpdatable<T> Set<T,TV>(
199 [NotNull] this IUpdatable<T> source,
200 [NotNull, InstantHandle] Expression<Func<T,TV>> extract,
201 [NotNull, InstantHandle] Expression<Func<T,TV>> update)
202 {
203 if (source == null) throw new ArgumentNullException("source");
204 if (extract == null) throw new ArgumentNullException("extract");
205 if (update == null) throw new ArgumentNullException("update");
206
207 var query = ((Updatable<T>)source).Query;
208
209 query = query.Provider.CreateQuery<T>(
210 Expression.Call(
211 null,
212 ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T), typeof(TV) }),
213 new[] { query.Expression, Expression.Quote(extract), Expression.Quote(update) }));
214
215 return new Updatable<T> { Query = query };
216 }
217
218 public static IUpdatable<T> Set<T,TV>(
219 [NotNull] this IQueryable<T> source,
220 [NotNull, InstantHandle] Expression<Func<T,TV>> extract,
221 [NotNull, InstantHandle] Expression<Func<TV>> update)
222 {
223 if (source == null) throw new ArgumentNullException("source");
224 if (extract == null) throw new ArgumentNullException("extract");
225 if (update == null) throw new ArgumentNullException("update");
226
227 var query = source.Provider.CreateQuery<T>(
228 Expression.Call(
229 null,
230 ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T), typeof(TV) }),
231 new[] { source.Expression, Expression.Quote(extract), Expression.Quote(update) }));
232
233 return new Updatable<T> { Query = query };
234 }
235
236 public static IUpdatable<T> Set<T,TV>(
237 [NotNull] this IUpdatable<T> source,
238 [NotNull, InstantHandle] Expression<Func<T,TV>> extract,
239 [NotNull, InstantHandle] Expression<Func<TV>> update)
240 {
241 if (source == null) throw new ArgumentNullException("source");
242 if (extract == null) throw new ArgumentNullException("extract");
243 if (update == null) throw new ArgumentNullException("update");
244
245 var query = ((Updatable<T>)source).Query;
246
247 query = query.Provider.CreateQuery<T>(
248 Expression.Call(
249 null,
250 ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T), typeof(TV) }),
251 new[] { query.Expression, Expression.Quote(extract), Expression.Quote(update) }));
252
253 return new Updatable<T> { Query = query };
254 }
255
256 public static IUpdatable<T> Set<T,TV>(
257 [NotNull] this IQueryable<T> source,
258 [NotNull, InstantHandle] Expression<Func<T,TV>> extract,
259 TV value)
260 {
261 if (source == null) throw new ArgumentNullException("source");
262 if (extract == null) throw new ArgumentNullException("extract");
263
264 var query = source.Provider.CreateQuery<T>(
265 Expression.Call(
266 null,
267 ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T), typeof(TV) }),
268 new[] { source.Expression, Expression.Quote(extract), Expression.Constant(value, typeof(TV)) }));
269
270 return new Updatable<T> { Query = query };
271 }
272
273 public static IUpdatable<T> Set<T,TV>(
274 [NotNull] this IUpdatable<T> source,
275 [NotNull, InstantHandle] Expression<Func<T,TV>> extract,
276 TV value)
277 {
278 if (source == null) throw new ArgumentNullException("source");
279 if (extract == null) throw new ArgumentNullException("extract");
280
281 var query = ((Updatable<T>)source).Query;
282
283 query = query.Provider.CreateQuery<T>(
284 Expression.Call(
285 null,
286 ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T), typeof(TV) }),
287 new[] { query.Expression, Expression.Quote(extract), Expression.Constant(value, typeof(TV)) }));
288
289 return new Updatable<T> { Query = query };
290 }
291
292 #endregion
293
294 #region Insert
295
296 public static int Insert<T>(
297 [NotNull] this Table<T> target,
298 [NotNull, InstantHandle] Expression<Func<T>> setter)
299 {
300 if (target == null) throw new ArgumentNullException("target");
301 if (setter == null) throw new ArgumentNullException("setter");
302
303 IQueryable<T> query = target;
304
305 return query.Provider.Execute<int>(
306 Expression.Call(
307 null,
308 ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T) }),
309 new[] { query.Expression, Expression.Quote(setter) }));
310 }
311
312 public static object InsertWithIdentity<T>(
313 [NotNull] this Table<T> target,
314 [NotNull, InstantHandle] Expression<Func<T>> setter)
315 {
316 if (target == null) throw new ArgumentNullException("target");
317 if (setter == null) throw new ArgumentNullException("setter");
318
319 IQueryable<T> query = target;
320
321 return query.Provider.Execute<object>(
322 Expression.Call(
323 null,
324 ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T) }),
325 new[] { query.Expression, Expression.Quote(setter) }));
326 }
327
328 #region ValueInsertable
329
330 class ValueInsertable<T> : IValueInsertable<T>
331 {
332 public IQueryable<T> Query;
333 }
334
335 public static IValueInsertable<T> Into<T>(this IDataContext dataContext, [NotNull] Table<T> target)
336 {
337 if (target == null) throw new ArgumentNullException("target");
338
339 IQueryable<T> query = target;
340
341 var q = query.Provider.CreateQuery<T>(
342 Expression.Call(
343 null,
344 ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T) }),
345 new[] { Expression.Constant(null, typeof(IDataContext)), query.Expression }));
346
347 return new ValueInsertable<T> { Query = q };
348 }
349
350 public static IValueInsertable<T> Value<T,TV>(
351 [NotNull] this Table<T> source,
352 [NotNull, InstantHandle] Expression<Func<T,TV>> field,
353 [NotNull, InstantHandle] Expression<Func<TV>> value)
354 {
355 if (source == null) throw new ArgumentNullException("source");
356 if (field == null) throw new ArgumentNullException("field");
357 if (value == null) throw new ArgumentNullException("value");
358
359 var query = (IQueryable<T>)source;
360
361 var q = query.Provider.CreateQuery<T>(
362 Expression.Call(
363 null,
364 ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T), typeof(TV) }),
365 new[] { query.Expression, Expression.Quote(field), Expression.Quote(value) }));
366
367 return new ValueInsertable<T> { Query = q };
368 }
369
370 public static IValueInsertable<T> Value<T,TV>(
371 [NotNull] this Table<T> source,
372 [NotNull, InstantHandle] Expression<Func<T,TV>> field,
373 TV value)
374 {
375 if (source == null) throw new ArgumentNullException("source");
376 if (field == null) throw new ArgumentNullException("field");
377
378 var query = (IQueryable<T>)source;
379
380 var q = query.Provider.CreateQuery<T>(
381 Expression.Call(
382 null,
383 ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T), typeof(TV) }),
384 new[] { query.Expression, Expression.Quote(field), Expression.Constant(value, typeof(TV)) }));
385
386 return new ValueInsertable<T> { Query = q };
387 }
388
389 public static IValueInsertable<T> Value<T,TV>(
390 [NotNull] this IValueInsertable<T> source,
391 [NotNull, InstantHandle] Expression<Func<T,TV>> field,
392 [NotNull, InstantHandle] Expression<Func<TV>> value)
393 {
394 if (source == null) throw new ArgumentNullException("source");
395 if (field == null) throw new ArgumentNullException("field");
396 if (value == null) throw new ArgumentNullException("value");
397
398 var query = ((ValueInsertable<T>)source).Query;
399
400 var q = query.Provider.CreateQuery<T>(
401 Expression.Call(
402 null,
403 ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T), typeof(TV) }),
404 new[] { query.Expression, Expression.Quote(field), Expression.Quote(value) }));
405
406 return new ValueInsertable<T> { Query = q };
407 }
408
409 public static IValueInsertable<T> Value<T,TV>(
410 [NotNull] this IValueInsertable<T> source,
411 [NotNull, InstantHandle] Expression<Func<T,TV>> field,
412 TV value)
413 {
414 if (source == null) throw new ArgumentNullException("source");
415 if (field == null) throw new ArgumentNullException("field");
416
417 var query = ((ValueInsertable<T>)source).Query;
418
419 var q = query.Provider.CreateQuery<T>(
420 Expression.Call(
421 null,
422 ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T), typeof(TV) }),
423 new[] { query.Expression, Expression.Quote(field), Expression.Constant(value, typeof(TV)) }));
424
425 return new ValueInsertable<T> { Query = q };
426 }
427
428 public static int Insert<T>([NotNull] this IValueInsertable<T> source)
429 {
430 if (source == null) throw new ArgumentNullException("source");
431
432 var query = ((ValueInsertable<T>)source).Query;
433
434 return query.Provider.Execute<int>(
435 Expression.Call(
436 null,
437 ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T) }),
438 new[] { query.Expression }));
439 }
440
441 public static object InsertWithIdentity<T>([NotNull] this IValueInsertable<T> source)
442 {
443 if (source == null) throw new ArgumentNullException("source");
444
445 var query = ((ValueInsertable<T>)source).Query;
446
447 return query.Provider.Execute<object>(
448 Expression.Call(
449 null,
450 ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T) }),
451 new[] { query.Expression }));
452 }
453
454 #endregion
455
456 #region SelectInsertable
457
458 public static int Insert<TSource,TTarget>(
459 [NotNull] this IQueryable<TSource> source,
460 [NotNull] Table<TTarget> target,
461 [NotNull, InstantHandle] Expression<Func<TSource, TTarget>> setter)
462 {
463 if (source == null) throw new ArgumentNullException("source");
464 if (target == null) throw new ArgumentNullException("target");
465 if (setter == null) throw new ArgumentNullException("setter");
466
467 return source.Provider.Execute<int>(
468 Expression.Call(
469 null,
470 ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(TSource), typeof(TTarget) }),
471 new[] { source.Expression, ((IQueryable<TTarget>)target).Expression, Expression.Quote(setter) }));
472 }
473
474 public static object InsertWithIdentity<TSource,TTarget>(
475 [NotNull] this IQueryable<TSource> source,
476 [NotNull] Table<TTarget> target,
477 [NotNull, InstantHandle] Expression<Func<TSource,TTarget>> setter)
478 {
479 if (source == null) throw new ArgumentNullException("source");
480 if (target == null) throw new ArgumentNullException("target");
481 if (setter == null) throw new ArgumentNullException("setter");
482
483 return source.Provider.Execute<object>(
484 Expression.Call(
485 null,
486 ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(TSource), typeof(TTarget) }),
487 new[] { source.Expression, ((IQueryable<TTarget>)target).Expression, Expression.Quote(setter) }));
488 }
489
490 class SelectInsertable<T,TT> : ISelectInsertable<T,TT>
491 {
492 public IQueryable<T> Query;
493 }
494
495 public static ISelectInsertable<TSource,TTarget> Into<TSource,TTarget>(
496 [NotNull] this IQueryable<TSource> source,
497 [NotNull] Table<TTarget> target)
498 {
499 if (target == null) throw new ArgumentNullException("target");
500
501 var q = source.Provider.CreateQuery<TSource>(
502 Expression.Call(
503 null,
504 ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(TSource), typeof(TTarget) }),
505 new[] { source.Expression, ((IQueryable<TTarget>)target).Expression }));
506
507 return new SelectInsertable<TSource,TTarget> { Query = q };
508 }
509
510 public static ISelectInsertable<TSource,TTarget> Value<TSource,TTarget,TValue>(
511 [NotNull] this ISelectInsertable<TSource,TTarget> source,
512 [NotNull, InstantHandle] Expression<Func<TTarget,TValue>> field,
513 [NotNull, InstantHandle] Expression<Func<TSource,TValue>> value)
514 {
515 if (source == null) throw new ArgumentNullException("source");
516 if (field == null) throw new ArgumentNullException("field");
517 if (value == null) throw new ArgumentNullException("value");
518
519 var query = ((SelectInsertable<TSource,TTarget>)source).Query;
520
521 var q = query.Provider.CreateQuery<TSource>(
522 Expression.Call(
523 null,
524 ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(TSource), typeof(TTarget), typeof(TValue) }),
525 new[] { query.Expression, Expression.Quote(field), Expression.Quote(value) }));
526
527 return new SelectInsertable<TSource,TTarget> { Query = q };
528 }
529
530 public static ISelectInsertable<TSource,TTarget> Value<TSource,TTarget,TValue>(
531 [NotNull] this ISelectInsertable<TSource,TTarget> source,
532 [NotNull, InstantHandle] Expression<Func<TTarget,TValue>> field,
533 [NotNull, InstantHandle] Expression<Func<TValue>> value)
534 {
535 if (source == null) throw new ArgumentNullException("source");
536 if (field == null) throw new ArgumentNullException("field");
537 if (value == null) throw new ArgumentNullException("value");
538
539 var query = ((SelectInsertable<TSource,TTarget>)source).Query;
540
541 var q = query.Provider.CreateQuery<TSource>(
542 Expression.Call(
543 null,
544 ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(TSource), typeof(TTarget), typeof(TValue) }),
545 new[] { query.Expression, Expression.Quote(field), Expression.Quote(value) }));
546
547 return new SelectInsertable<TSource,TTarget> { Query = q };
548 }
549
550 public static ISelectInsertable<TSource,TTarget> Value<TSource,TTarget,TValue>(
551 [NotNull] this ISelectInsertable<TSource,TTarget> source,
552 [NotNull, InstantHandle] Expression<Func<TTarget,TValue>> field,
553 TValue value)
554 {
555 if (source == null) throw new ArgumentNullException("source");
556 if (field == null) throw new ArgumentNullException("field");
557
558 var query = ((SelectInsertable<TSource,TTarget>)source).Query;
559
560 var q = query.Provider.CreateQuery<TSource>(
561 Expression.Call(
562 null,
563 ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(TSource), typeof(TTarget), typeof(TValue) }),
564 new[] { query.Expression, Expression.Quote(field), Expression.Constant(value, typeof(TValue)) }));
565
566 return new SelectInsertable<TSource,TTarget> { Query = q };
567 }
568
569 public static int Insert<TSource,TTarget>([NotNull] this ISelectInsertable<TSource,TTarget> source)
570 {
571 if (source == null) throw new ArgumentNullException("source");
572
573 var query = ((SelectInsertable<TSource,TTarget>)source).Query;
574
575 return query.Provider.Execute<int>(
576 Expression.Call(
577 null,
578 ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(TSource), typeof(TTarget) }),
579 new[] { query.Expression }));
580 }
581
582 public static object InsertWithIdentity<TSource,TTarget>([NotNull] this ISelectInsertable<TSource,TTarget> source)
583 {
584 if (source == null) throw new ArgumentNullException("source");
585
586 var query = ((SelectInsertable<TSource,TTarget>)source).Query;
587
588 return query.Provider.Execute<object>(
589 Expression.Call(
590 null,
591 ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(TSource), typeof(TTarget) }),
592 new[] { query.Expression }));
593 }
594
595 #endregion
596
597 #endregion
598
599 #region InsertOrUpdate
600
601 public static int InsertOrUpdate<T>(
602 [NotNull] this Table<T> target,
603 [NotNull, InstantHandle] Expression<Func<T>> insertSetter,
604 [NotNull, InstantHandle] Expression<Func<T,T>> onDuplicateKeyUpdateSetter)
605 {
606 if (target == null) throw new ArgumentNullException("target");
607 if (insertSetter == null) throw new ArgumentNullException("insertSetter");
608 if (onDuplicateKeyUpdateSetter == null) throw new ArgumentNullException("onDuplicateKeyUpdateSetter");
609
610 IQueryable<T> query = target;
611
612 return query.Provider.Execute<int>(
613 Expression.Call(
614 null,
615 ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T) }),
616 new[] { query.Expression, Expression.Quote(insertSetter), Expression.Quote(onDuplicateKeyUpdateSetter) }));
617 }
618
619 public static int InsertOrUpdate<T>(
620 [NotNull] this Table<T> target,
621 [NotNull, InstantHandle] Expression<Func<T>> insertSetter,
622 [NotNull, InstantHandle] Expression<Func<T,T>> onDuplicateKeyUpdateSetter,
623 [NotNull, InstantHandle] Expression<Func<T>> keySelector)
624 {
625 if (target == null) throw new ArgumentNullException("target");
626 if (insertSetter == null) throw new ArgumentNullException("insertSetter");
627 if (onDuplicateKeyUpdateSetter == null) throw new ArgumentNullException("onDuplicateKeyUpdateSetter");
628 if (keySelector == null) throw new ArgumentNullException("keySelector");
629
630 IQueryable<T> query = target;
631
632 return query.Provider.Execute<int>(
633 Expression.Call(
634 null,
635 ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(T) }),
636 new[]
637 {
638 query.Expression,
639 Expression.Quote(insertSetter),
640 Expression.Quote(onDuplicateKeyUpdateSetter),
641 Expression.Quote(keySelector)
642 }));
643 }
644
645 #endregion
646
647 #region Take / Skip / ElementAt
648
649 public static IQueryable<TSource> Take<TSource>(
650 [NotNull] this IQueryable<TSource> source,
651 [NotNull, InstantHandle] Expression<Func<int>> count)
652 {
653 if (source == null) throw new ArgumentNullException("source");
654 if (count == null) throw new ArgumentNullException("count");
655
656 return source.Provider.CreateQuery<TSource>(
657 Expression.Call(
658 null,
659 ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(TSource) }),
660 new[] { source.Expression, Expression.Quote(count) }));
661 }
662
663 public static IQueryable<TSource> Skip<TSource>(
664 [NotNull] this IQueryable<TSource> source,
665 [NotNull, InstantHandle] Expression<Func<int>> count)
666 {
667 if (source == null) throw new ArgumentNullException("source");
668 if (count == null) throw new ArgumentNullException("count");
669
670 return source.Provider.CreateQuery<TSource>(
671 Expression.Call(
672 null,
673 ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(TSource) }),
674 new[] { source.Expression, Expression.Quote(count) }));
675 }
676
677 public static TSource ElementAt<TSource>(
678 [NotNull] this IQueryable<TSource> source,
679 [NotNull, InstantHandle] Expression<Func<int>> index)
680 {
681 if (source == null) throw new ArgumentNullException("source");
682 if (index == null) throw new ArgumentNullException("index");
683
684 return source.Provider.Execute<TSource>(
685 Expression.Call(
686 null,
687 ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(TSource) }),
688 new[] { source.Expression, Expression.Quote(index) }));
689 }
690
691 public static TSource ElementAtOrDefault<TSource>(
692 [NotNull] this IQueryable<TSource> source,
693 [NotNull, InstantHandle] Expression<Func<int>> index)
694 {
695 if (source == null) throw new ArgumentNullException("source");
696 if (index == null) throw new ArgumentNullException("index");
697
698 return source.Provider.Execute<TSource>(
699 Expression.Call(
700 null,
701 ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new[] { typeof(TSource) }),
702 new[] { source.Expression, Expression.Quote(index) }));
703 }
704
705 #endregion
706
707 #region Stub helpers
708
709 static TOutput Where<TOutput,TSource,TInput>(this TInput source, Func<TSource,bool> predicate)
710 {
711 throw new InvalidOperationException();
712 }
713
714 #endregion
715 }
716 }