Mercurial > pub > bltoolkit
comparison Source/Data/Sql/QueryVisitor.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.Collections.Generic; | |
3 | |
4 namespace BLToolkit.Data.Sql | |
5 { | |
6 using VisitFunc = Func<IQueryElement,bool>; | |
7 using FindFunc = Func<IQueryElement,bool>; | |
8 using ConvertFunc = Func<IQueryElement,IQueryElement>; | |
9 | |
10 public class QueryVisitor | |
11 { | |
12 #region Visit | |
13 | |
14 readonly Dictionary<IQueryElement,IQueryElement> _visitedElements = new Dictionary<IQueryElement, IQueryElement>(); | |
15 public Dictionary<IQueryElement,IQueryElement> VisitedElements | |
16 { | |
17 get { return _visitedElements; } | |
18 } | |
19 | |
20 bool _all; | |
21 Func<IQueryElement,bool> _action1; | |
22 Action<IQueryElement> _action2; | |
23 | |
24 public void VisitParentFirst(IQueryElement element, Func<IQueryElement,bool> action) | |
25 { | |
26 _visitedElements.Clear(); | |
27 _action1 = action; | |
28 Visit1(element); | |
29 } | |
30 | |
31 void Visit1(IQueryElement element) | |
32 { | |
33 if (element == null || _visitedElements.ContainsKey(element)) | |
34 return; | |
35 | |
36 _visitedElements.Add(element, element); | |
37 | |
38 if (!_action1(element)) | |
39 return; | |
40 | |
41 switch (element.ElementType) | |
42 { | |
43 case QueryElementType.SqlFunction: | |
44 { | |
45 foreach (var p in ((SqlFunction)element).Parameters) Visit1(p); | |
46 break; | |
47 } | |
48 | |
49 case QueryElementType.SqlExpression: | |
50 { | |
51 foreach (var v in ((SqlExpression)element).Parameters) Visit1(v); | |
52 break; | |
53 } | |
54 | |
55 case QueryElementType.SqlBinaryExpression: | |
56 { | |
57 //var bexpr = (SqlBinaryExpression)element; | |
58 Visit1(((SqlBinaryExpression)element).Expr1); | |
59 Visit1(((SqlBinaryExpression)element).Expr2); | |
60 break; | |
61 } | |
62 | |
63 case QueryElementType.SqlTable: | |
64 { | |
65 var table = (SqlTable)element; | |
66 | |
67 Visit1(table.All); | |
68 foreach (var field in table.Fields.Values) Visit1(field); | |
69 foreach (var join in table.Joins) Visit1(join); | |
70 | |
71 if (table.TableArguments != null) | |
72 foreach (var a in table.TableArguments) Visit1(a); | |
73 | |
74 break; | |
75 } | |
76 | |
77 case QueryElementType.Join: | |
78 { | |
79 foreach (var j in ((Join)element).JoinOns) Visit1(j); | |
80 break; | |
81 } | |
82 | |
83 case QueryElementType.Column: | |
84 { | |
85 Visit1(((SqlQuery.Column)element).Expression); | |
86 break; | |
87 } | |
88 | |
89 case QueryElementType.TableSource: | |
90 { | |
91 //var table = ((SqlQuery.TableSource)element); | |
92 | |
93 Visit1(((SqlQuery.TableSource)element).Source); | |
94 foreach (var j in ((SqlQuery.TableSource)element).Joins) Visit1(j); | |
95 break; | |
96 } | |
97 | |
98 case QueryElementType.JoinedTable: | |
99 { | |
100 //var join = (SqlQuery.JoinedTable)element; | |
101 Visit1(((SqlQuery.JoinedTable)element).Table); | |
102 Visit1(((SqlQuery.JoinedTable)element).Condition); | |
103 break; | |
104 } | |
105 | |
106 case QueryElementType.SearchCondition: | |
107 { | |
108 foreach (var c in ((SqlQuery.SearchCondition)element).Conditions) Visit1(c); | |
109 break; | |
110 } | |
111 | |
112 case QueryElementType.Condition: | |
113 { | |
114 Visit1(((SqlQuery.Condition)element).Predicate); | |
115 break; | |
116 } | |
117 | |
118 case QueryElementType.ExprPredicate: | |
119 { | |
120 Visit1(((SqlQuery.Predicate.Expr)element).Expr1); | |
121 break; | |
122 } | |
123 | |
124 case QueryElementType.NotExprPredicate: | |
125 { | |
126 Visit1(((SqlQuery.Predicate.NotExpr)element).Expr1); | |
127 break; | |
128 } | |
129 | |
130 case QueryElementType.ExprExprPredicate: | |
131 { | |
132 //var p = ((SqlQuery.Predicate.ExprExpr)element); | |
133 Visit1(((SqlQuery.Predicate.ExprExpr)element).Expr1); | |
134 Visit1(((SqlQuery.Predicate.ExprExpr)element).Expr2); | |
135 break; | |
136 } | |
137 | |
138 case QueryElementType.LikePredicate: | |
139 { | |
140 //var p = ((SqlQuery.Predicate.Like)element); | |
141 Visit1(((SqlQuery.Predicate.Like)element).Expr1); | |
142 Visit1(((SqlQuery.Predicate.Like)element).Expr2); | |
143 Visit1(((SqlQuery.Predicate.Like)element).Escape); | |
144 break; | |
145 } | |
146 | |
147 case QueryElementType.BetweenPredicate: | |
148 { | |
149 //var p = (SqlQuery.Predicate.Between)element; | |
150 Visit1(((SqlQuery.Predicate.Between)element).Expr1); | |
151 Visit1(((SqlQuery.Predicate.Between)element).Expr2); | |
152 Visit1(((SqlQuery.Predicate.Between)element).Expr3); | |
153 break; | |
154 } | |
155 | |
156 case QueryElementType.IsNullPredicate: | |
157 { | |
158 Visit1(((SqlQuery.Predicate.IsNull)element).Expr1); | |
159 break; | |
160 } | |
161 | |
162 case QueryElementType.InSubQueryPredicate: | |
163 { | |
164 //var p = (SqlQuery.Predicate.InSubQuery)element; | |
165 Visit1(((SqlQuery.Predicate.InSubQuery)element).Expr1); | |
166 Visit1(((SqlQuery.Predicate.InSubQuery)element).SubQuery); | |
167 break; | |
168 } | |
169 | |
170 case QueryElementType.InListPredicate: | |
171 { | |
172 //var p = (SqlQuery.Predicate.InList)element; | |
173 Visit1(((SqlQuery.Predicate.InList)element).Expr1); | |
174 foreach (var value in ((SqlQuery.Predicate.InList)element).Values) Visit1(value); | |
175 break; | |
176 } | |
177 | |
178 case QueryElementType.FuncLikePredicate: | |
179 { | |
180 Visit1(((SqlQuery.Predicate.FuncLike)element).Function); | |
181 break; | |
182 } | |
183 | |
184 case QueryElementType.SetExpression: | |
185 { | |
186 //var s = (SqlQuery.SetExpression)element; | |
187 Visit1(((SqlQuery.SetExpression)element).Column); | |
188 Visit1(((SqlQuery.SetExpression)element).Expression); | |
189 break; | |
190 } | |
191 | |
192 case QueryElementType.InsertClause: | |
193 { | |
194 //var sc = (SqlQuery.InsertClause)element; | |
195 | |
196 if (((SqlQuery.InsertClause)element).Into != null) | |
197 Visit1(((SqlQuery.InsertClause)element).Into); | |
198 | |
199 foreach (var c in ((SqlQuery.InsertClause)element).Items.ToArray()) Visit1(c); | |
200 break; | |
201 } | |
202 | |
203 case QueryElementType.UpdateClause: | |
204 { | |
205 //var sc = (SqlQuery.UpdateClause)element; | |
206 | |
207 if (((SqlQuery.UpdateClause)element).Table != null) | |
208 Visit1(((SqlQuery.UpdateClause)element).Table); | |
209 | |
210 foreach (var c in ((SqlQuery.UpdateClause)element).Items.ToArray()) Visit1(c); | |
211 foreach (var c in ((SqlQuery.UpdateClause)element).Keys. ToArray()) Visit1(c); | |
212 break; | |
213 } | |
214 | |
215 case QueryElementType.DeleteClause: | |
216 { | |
217 if (((SqlQuery.DeleteClause)element).Table != null) | |
218 Visit1(((SqlQuery.DeleteClause)element).Table); | |
219 break; | |
220 } | |
221 | |
222 case QueryElementType.SelectClause: | |
223 { | |
224 //var sc = (SqlQuery.SelectClause)element; | |
225 Visit1(((SqlQuery.SelectClause)element).TakeValue); | |
226 Visit1(((SqlQuery.SelectClause)element).SkipValue); | |
227 | |
228 foreach (var c in ((SqlQuery.SelectClause)element).Columns.ToArray()) Visit1(c); | |
229 break; | |
230 } | |
231 | |
232 case QueryElementType.FromClause: | |
233 { | |
234 foreach (var t in ((SqlQuery.FromClause)element).Tables) Visit1(t); | |
235 break; | |
236 } | |
237 | |
238 case QueryElementType.WhereClause: | |
239 { | |
240 Visit1(((SqlQuery.WhereClause)element).SearchCondition); | |
241 break; | |
242 } | |
243 | |
244 case QueryElementType.GroupByClause: | |
245 { | |
246 foreach (var i in ((SqlQuery.GroupByClause)element).Items) Visit1(i); | |
247 break; | |
248 } | |
249 | |
250 case QueryElementType.OrderByClause: | |
251 { | |
252 foreach (var i in ((SqlQuery.OrderByClause)element).Items) Visit1(i); | |
253 break; | |
254 } | |
255 | |
256 case QueryElementType.OrderByItem: | |
257 { | |
258 Visit1(((SqlQuery.OrderByItem)element).Expression); | |
259 break; | |
260 } | |
261 | |
262 case QueryElementType.Union: | |
263 Visit1(((SqlQuery.Union)element).SqlQuery); | |
264 break; | |
265 | |
266 case QueryElementType.SqlQuery: | |
267 { | |
268 if (_all) | |
269 { | |
270 if (_visitedElements.ContainsKey(element)) | |
271 return; | |
272 _visitedElements.Add(element, element); | |
273 } | |
274 | |
275 var q = (SqlQuery)element; | |
276 | |
277 switch (q.QueryType) | |
278 { | |
279 case QueryType.InsertOrUpdate : | |
280 Visit1(q.Insert); | |
281 Visit1(q.Update); | |
282 | |
283 if (q.From.Tables.Count == 0) | |
284 break; | |
285 | |
286 goto default; | |
287 | |
288 case QueryType.Update : | |
289 Visit1(q.Update); | |
290 break; | |
291 | |
292 case QueryType.Delete : | |
293 Visit1(q.Delete); | |
294 Visit1(q.Select); | |
295 break; | |
296 | |
297 case QueryType.Insert : | |
298 Visit1(q.Insert); | |
299 | |
300 if (q.From.Tables.Count != 0) | |
301 Visit1(q.Select); | |
302 | |
303 break; | |
304 | |
305 default : | |
306 Visit1(q.Select); | |
307 break; | |
308 } | |
309 | |
310 Visit1(q.From); | |
311 Visit1(q.Where); | |
312 Visit1(q.GroupBy); | |
313 Visit1(q.Having); | |
314 Visit1(q.OrderBy); | |
315 | |
316 if (q.HasUnion) | |
317 { | |
318 foreach (var i in q.Unions) | |
319 { | |
320 if (i.SqlQuery == q) | |
321 throw new InvalidOperationException(); | |
322 | |
323 Visit1(i); | |
324 } | |
325 } | |
326 | |
327 break; | |
328 } | |
329 } | |
330 } | |
331 | |
332 public void Visit(IQueryElement element, Action<IQueryElement> action) | |
333 { | |
334 _visitedElements.Clear(); | |
335 _all = false; | |
336 _action2 = action; | |
337 Visit2(element); | |
338 } | |
339 | |
340 public void VisitAll(IQueryElement element, Action<IQueryElement> action) | |
341 { | |
342 _visitedElements.Clear(); | |
343 _all = true; | |
344 _action2 = action; | |
345 Visit2(element); | |
346 } | |
347 | |
348 void Visit2(IQueryElement element) | |
349 { | |
350 if (element == null || !_all && _visitedElements.ContainsKey(element)) | |
351 return; | |
352 | |
353 switch (element.ElementType) | |
354 { | |
355 case QueryElementType.SqlFunction: | |
356 { | |
357 foreach (var p in ((SqlFunction)element).Parameters) Visit2(p); | |
358 break; | |
359 } | |
360 | |
361 case QueryElementType.SqlExpression: | |
362 { | |
363 foreach (var v in ((SqlExpression)element).Parameters) Visit2(v); | |
364 break; | |
365 } | |
366 | |
367 case QueryElementType.SqlBinaryExpression: | |
368 { | |
369 //var bexpr = (SqlBinaryExpression)element; | |
370 Visit2(((SqlBinaryExpression)element).Expr1); | |
371 Visit2(((SqlBinaryExpression)element).Expr2); | |
372 break; | |
373 } | |
374 | |
375 case QueryElementType.SqlTable: | |
376 { | |
377 var table = (SqlTable)element; | |
378 | |
379 Visit2(table.All); | |
380 foreach (var field in table.Fields.Values) Visit2(field); | |
381 foreach (var join in table.Joins) Visit2(join); | |
382 | |
383 if (table.TableArguments != null) | |
384 foreach (var a in table.TableArguments) Visit2(a); | |
385 | |
386 break; | |
387 } | |
388 | |
389 case QueryElementType.Join: | |
390 { | |
391 foreach (var j in ((Join)element).JoinOns) Visit2(j); | |
392 break; | |
393 } | |
394 | |
395 case QueryElementType.Column: | |
396 { | |
397 Visit2(((SqlQuery.Column)element).Expression); | |
398 break; | |
399 } | |
400 | |
401 case QueryElementType.TableSource: | |
402 { | |
403 //var table = ((SqlQuery.TableSource)element); | |
404 | |
405 Visit2(((SqlQuery.TableSource)element).Source); | |
406 foreach (var j in ((SqlQuery.TableSource)element).Joins) Visit2(j); | |
407 break; | |
408 } | |
409 | |
410 case QueryElementType.JoinedTable: | |
411 { | |
412 //var join = (SqlQuery.JoinedTable)element; | |
413 Visit2(((SqlQuery.JoinedTable)element).Table); | |
414 Visit2(((SqlQuery.JoinedTable)element).Condition); | |
415 break; | |
416 } | |
417 | |
418 case QueryElementType.SearchCondition: | |
419 { | |
420 foreach (var c in ((SqlQuery.SearchCondition)element).Conditions) Visit2(c); | |
421 break; | |
422 } | |
423 | |
424 case QueryElementType.Condition: | |
425 { | |
426 Visit2(((SqlQuery.Condition)element).Predicate); | |
427 break; | |
428 } | |
429 | |
430 case QueryElementType.ExprPredicate: | |
431 { | |
432 Visit2(((SqlQuery.Predicate.Expr)element).Expr1); | |
433 break; | |
434 } | |
435 | |
436 case QueryElementType.NotExprPredicate: | |
437 { | |
438 Visit2(((SqlQuery.Predicate.NotExpr)element).Expr1); | |
439 break; | |
440 } | |
441 | |
442 case QueryElementType.ExprExprPredicate: | |
443 { | |
444 //var p = ((SqlQuery.Predicate.ExprExpr)element); | |
445 Visit2(((SqlQuery.Predicate.ExprExpr)element).Expr1); | |
446 Visit2(((SqlQuery.Predicate.ExprExpr)element).Expr2); | |
447 break; | |
448 } | |
449 | |
450 case QueryElementType.LikePredicate: | |
451 { | |
452 //var p = ((SqlQuery.Predicate.Like)element); | |
453 Visit2(((SqlQuery.Predicate.Like)element).Expr1); | |
454 Visit2(((SqlQuery.Predicate.Like)element).Expr2); | |
455 Visit2(((SqlQuery.Predicate.Like)element).Escape); | |
456 break; | |
457 } | |
458 | |
459 case QueryElementType.BetweenPredicate: | |
460 { | |
461 //var p = (SqlQuery.Predicate.Between)element; | |
462 Visit2(((SqlQuery.Predicate.Between)element).Expr1); | |
463 Visit2(((SqlQuery.Predicate.Between)element).Expr2); | |
464 Visit2(((SqlQuery.Predicate.Between)element).Expr3); | |
465 break; | |
466 } | |
467 | |
468 case QueryElementType.IsNullPredicate: | |
469 { | |
470 Visit2(((SqlQuery.Predicate.IsNull)element).Expr1); | |
471 break; | |
472 } | |
473 | |
474 case QueryElementType.InSubQueryPredicate: | |
475 { | |
476 //var p = (SqlQuery.Predicate.InSubQuery)element; | |
477 Visit2(((SqlQuery.Predicate.InSubQuery)element).Expr1); | |
478 Visit2(((SqlQuery.Predicate.InSubQuery)element).SubQuery); | |
479 break; | |
480 } | |
481 | |
482 case QueryElementType.InListPredicate: | |
483 { | |
484 //var p = (SqlQuery.Predicate.InList)element; | |
485 Visit2(((SqlQuery.Predicate.InList)element).Expr1); | |
486 foreach (var value in ((SqlQuery.Predicate.InList)element).Values) Visit2(value); | |
487 break; | |
488 } | |
489 | |
490 case QueryElementType.FuncLikePredicate: | |
491 { | |
492 Visit2(((SqlQuery.Predicate.FuncLike)element).Function); | |
493 break; | |
494 } | |
495 | |
496 case QueryElementType.SetExpression: | |
497 { | |
498 //var s = (SqlQuery.SetExpression)element; | |
499 Visit2(((SqlQuery.SetExpression)element).Column); | |
500 Visit2(((SqlQuery.SetExpression)element).Expression); | |
501 break; | |
502 } | |
503 | |
504 case QueryElementType.InsertClause: | |
505 { | |
506 //var sc = (SqlQuery.InsertClause)element; | |
507 | |
508 if (((SqlQuery.InsertClause)element).Into != null) | |
509 Visit2(((SqlQuery.InsertClause)element).Into); | |
510 | |
511 foreach (var c in ((SqlQuery.InsertClause)element).Items.ToArray()) Visit2(c); | |
512 break; | |
513 } | |
514 | |
515 case QueryElementType.UpdateClause: | |
516 { | |
517 //var sc = (SqlQuery.UpdateClause)element; | |
518 | |
519 if (((SqlQuery.UpdateClause)element).Table != null) | |
520 Visit2(((SqlQuery.UpdateClause)element).Table); | |
521 | |
522 foreach (var c in ((SqlQuery.UpdateClause)element).Items.ToArray()) Visit2(c); | |
523 foreach (var c in ((SqlQuery.UpdateClause)element).Keys. ToArray()) Visit2(c); | |
524 break; | |
525 } | |
526 | |
527 case QueryElementType.DeleteClause: | |
528 { | |
529 if (((SqlQuery.DeleteClause)element).Table != null) | |
530 Visit2(((SqlQuery.DeleteClause)element).Table); | |
531 break; | |
532 } | |
533 | |
534 case QueryElementType.SelectClause: | |
535 { | |
536 //var sc = (SqlQuery.SelectClause)element; | |
537 Visit2(((SqlQuery.SelectClause)element).TakeValue); | |
538 Visit2(((SqlQuery.SelectClause)element).SkipValue); | |
539 | |
540 foreach (var c in ((SqlQuery.SelectClause)element).Columns.ToArray()) Visit2(c); | |
541 break; | |
542 } | |
543 | |
544 case QueryElementType.FromClause: | |
545 { | |
546 foreach (var t in ((SqlQuery.FromClause)element).Tables) Visit2(t); | |
547 break; | |
548 } | |
549 | |
550 case QueryElementType.WhereClause: | |
551 { | |
552 Visit2(((SqlQuery.WhereClause)element).SearchCondition); | |
553 break; | |
554 } | |
555 | |
556 case QueryElementType.GroupByClause: | |
557 { | |
558 foreach (var i in ((SqlQuery.GroupByClause)element).Items) Visit2(i); | |
559 break; | |
560 } | |
561 | |
562 case QueryElementType.OrderByClause: | |
563 { | |
564 foreach (var i in ((SqlQuery.OrderByClause)element).Items) Visit2(i); | |
565 break; | |
566 } | |
567 | |
568 case QueryElementType.OrderByItem: | |
569 { | |
570 Visit2(((SqlQuery.OrderByItem)element).Expression); | |
571 break; | |
572 } | |
573 | |
574 case QueryElementType.Union: | |
575 Visit2(((SqlQuery.Union)element).SqlQuery); | |
576 break; | |
577 | |
578 case QueryElementType.SqlQuery: | |
579 { | |
580 if (_all) | |
581 { | |
582 if (_visitedElements.ContainsKey(element)) | |
583 return; | |
584 _visitedElements.Add(element, element); | |
585 } | |
586 | |
587 var q = (SqlQuery)element; | |
588 | |
589 switch (q.QueryType) | |
590 { | |
591 case QueryType.InsertOrUpdate : | |
592 Visit2(q.Insert); | |
593 Visit2(q.Update); | |
594 | |
595 if (q.From.Tables.Count == 0) | |
596 break; | |
597 | |
598 goto default; | |
599 | |
600 case QueryType.Update : | |
601 Visit2(q.Update); | |
602 break; | |
603 | |
604 case QueryType.Delete : | |
605 Visit2(q.Delete); | |
606 Visit2(q.Select); | |
607 break; | |
608 | |
609 case QueryType.Insert : | |
610 Visit2(q.Insert); | |
611 | |
612 if (q.From.Tables.Count != 0) | |
613 Visit2(q.Select); | |
614 | |
615 break; | |
616 | |
617 default : | |
618 Visit2(q.Select); | |
619 break; | |
620 } | |
621 | |
622 // Visit2(q.From); | |
623 // | |
624 if (q.From != null && (_all || !_visitedElements.ContainsKey(q.From))) | |
625 { | |
626 foreach (var t in q.From.Tables) | |
627 { | |
628 //Visit2(t); | |
629 // | |
630 if (t != null && (_all || !_visitedElements.ContainsKey(t))) | |
631 { | |
632 Visit2(t.Source); | |
633 | |
634 foreach (var j in t.Joins) | |
635 Visit2(j); | |
636 | |
637 _action2(t); | |
638 if (!_all) | |
639 _visitedElements.Add(t, t); | |
640 } | |
641 } | |
642 _action2(q.From); | |
643 if (!_all) | |
644 _visitedElements.Add(q.From, q.From); | |
645 } | |
646 | |
647 Visit2(q.Where); | |
648 Visit2(q.GroupBy); | |
649 Visit2(q.Having); | |
650 Visit2(q.OrderBy); | |
651 | |
652 if (q.HasUnion) | |
653 { | |
654 foreach (var i in q.Unions) | |
655 { | |
656 if (i.SqlQuery == q) | |
657 throw new InvalidOperationException(); | |
658 | |
659 Visit2(i); | |
660 } | |
661 } | |
662 | |
663 break; | |
664 } | |
665 } | |
666 | |
667 _action2(element); | |
668 if (!_all) | |
669 _visitedElements.Add(element, element); | |
670 } | |
671 | |
672 #endregion | |
673 | |
674 #region Find | |
675 | |
676 IQueryElement Find<T>(IEnumerable<T> arr, FindFunc find) | |
677 where T : class, IQueryElement | |
678 { | |
679 if (arr == null) | |
680 return null; | |
681 | |
682 foreach (var item in arr) | |
683 { | |
684 var e = Find(item, find); | |
685 if (e != null) | |
686 return e; | |
687 } | |
688 | |
689 return null; | |
690 } | |
691 | |
692 public IQueryElement Find(IQueryElement element, FindFunc find) | |
693 { | |
694 if (element == null || find(element)) | |
695 return element; | |
696 | |
697 switch (element.ElementType) | |
698 { | |
699 case QueryElementType.SqlFunction : return Find(((SqlFunction) element).Parameters, find); | |
700 case QueryElementType.SqlExpression : return Find(((SqlExpression) element).Parameters, find); | |
701 case QueryElementType.Join : return Find(((Join) element).JoinOns, find); | |
702 case QueryElementType.Column : return Find(((SqlQuery.Column) element).Expression, find); | |
703 case QueryElementType.SearchCondition : return Find(((SqlQuery.SearchCondition) element).Conditions, find); | |
704 case QueryElementType.Condition : return Find(((SqlQuery.Condition) element).Predicate, find); | |
705 case QueryElementType.ExprPredicate : return Find(((SqlQuery.Predicate.Expr) element).Expr1, find); | |
706 case QueryElementType.NotExprPredicate : return Find(((SqlQuery.Predicate.NotExpr) element).Expr1, find); | |
707 case QueryElementType.IsNullPredicate : return Find(((SqlQuery.Predicate.IsNull) element).Expr1, find); | |
708 case QueryElementType.FromClause : return Find(((SqlQuery.FromClause) element).Tables, find); | |
709 case QueryElementType.WhereClause : return Find(((SqlQuery.WhereClause) element).SearchCondition, find); | |
710 case QueryElementType.GroupByClause : return Find(((SqlQuery.GroupByClause) element).Items, find); | |
711 case QueryElementType.OrderByClause : return Find(((SqlQuery.OrderByClause) element).Items, find); | |
712 case QueryElementType.OrderByItem : return Find(((SqlQuery.OrderByItem) element).Expression, find); | |
713 case QueryElementType.Union : return Find(((SqlQuery.Union) element).SqlQuery, find); | |
714 case QueryElementType.FuncLikePredicate : return Find(((SqlQuery.Predicate.FuncLike)element).Function, find); | |
715 | |
716 case QueryElementType.SqlBinaryExpression: | |
717 { | |
718 var bexpr = (SqlBinaryExpression)element; | |
719 return | |
720 Find(bexpr.Expr1, find) ?? | |
721 Find(bexpr.Expr2, find); | |
722 } | |
723 | |
724 case QueryElementType.SqlTable: | |
725 { | |
726 var table = (SqlTable)element; | |
727 return | |
728 Find(table.All, find) ?? | |
729 Find(table.Fields.Values, find) ?? | |
730 Find(table.Joins, find) ?? | |
731 Find(table.TableArguments, find); | |
732 } | |
733 | |
734 case QueryElementType.TableSource: | |
735 { | |
736 var table = (SqlQuery.TableSource)element; | |
737 return | |
738 Find(table.Source, find) ?? | |
739 Find(table.Joins, find); | |
740 } | |
741 | |
742 case QueryElementType.JoinedTable: | |
743 { | |
744 var join = (SqlQuery.JoinedTable)element; | |
745 return | |
746 Find(join.Table, find) ?? | |
747 Find(join.Condition, find); | |
748 } | |
749 | |
750 case QueryElementType.ExprExprPredicate: | |
751 { | |
752 var p = (SqlQuery.Predicate.ExprExpr)element; | |
753 return | |
754 Find(p.Expr1, find) ?? | |
755 Find(p.Expr2, find); | |
756 } | |
757 | |
758 case QueryElementType.LikePredicate: | |
759 { | |
760 var p = (SqlQuery.Predicate.Like)element; | |
761 return | |
762 Find(p.Expr1, find) ?? | |
763 Find(p.Expr2, find) ?? | |
764 Find(p.Escape, find); | |
765 } | |
766 | |
767 case QueryElementType.BetweenPredicate: | |
768 { | |
769 var p = (SqlQuery.Predicate.Between)element; | |
770 return | |
771 Find(p.Expr1, find) ?? | |
772 Find(p.Expr2, find) ?? | |
773 Find(p.Expr3, find); | |
774 } | |
775 | |
776 case QueryElementType.InSubQueryPredicate: | |
777 { | |
778 var p = (SqlQuery.Predicate.InSubQuery)element; | |
779 return | |
780 Find(p.Expr1, find) ?? | |
781 Find(p.SubQuery, find); | |
782 } | |
783 | |
784 case QueryElementType.InListPredicate: | |
785 { | |
786 var p = (SqlQuery.Predicate.InList)element; | |
787 return | |
788 Find(p.Expr1, find) ?? | |
789 Find(p.Values, find); | |
790 } | |
791 | |
792 case QueryElementType.SetExpression: | |
793 { | |
794 var s = (SqlQuery.SetExpression)element; | |
795 return | |
796 Find(s.Column, find) ?? | |
797 Find(s.Expression, find); | |
798 } | |
799 | |
800 case QueryElementType.InsertClause: | |
801 { | |
802 var sc = (SqlQuery.InsertClause)element; | |
803 return | |
804 Find(sc.Into, find) ?? | |
805 Find(sc.Items, find); | |
806 } | |
807 | |
808 case QueryElementType.UpdateClause: | |
809 { | |
810 var sc = (SqlQuery.UpdateClause)element; | |
811 return | |
812 Find(sc.Table, find) ?? | |
813 Find(sc.Items, find) ?? | |
814 Find(sc.Keys, find); | |
815 } | |
816 | |
817 case QueryElementType.DeleteClause: | |
818 { | |
819 var sc = (SqlQuery.DeleteClause)element; | |
820 return Find(sc.Table, find); | |
821 } | |
822 | |
823 case QueryElementType.SelectClause: | |
824 { | |
825 var sc = (SqlQuery.SelectClause)element; | |
826 return | |
827 Find(sc.TakeValue, find) ?? | |
828 Find(sc.SkipValue, find) ?? | |
829 Find(sc.Columns, find); | |
830 } | |
831 | |
832 case QueryElementType.SqlQuery: | |
833 { | |
834 var q = (SqlQuery)element; | |
835 return | |
836 Find(q.Select, find) ?? | |
837 (q.IsInsert ? Find(q.Insert, find) : null) ?? | |
838 (q.IsUpdate ? Find(q.Update, find) : null) ?? | |
839 Find(q.From, find) ?? | |
840 Find(q.Where, find) ?? | |
841 Find(q.GroupBy, find) ?? | |
842 Find(q.Having, find) ?? | |
843 Find(q.OrderBy, find) ?? | |
844 (q.HasUnion ? Find(q.Unions, find) : null); | |
845 } | |
846 } | |
847 | |
848 return null; | |
849 } | |
850 | |
851 #endregion | |
852 | |
853 #region Convert | |
854 | |
855 public T Convert<T>(T element, ConvertFunc action) | |
856 where T : class, IQueryElement | |
857 { | |
858 _visitedElements.Clear(); | |
859 return (T)ConvertInternal(element, action) ?? element; | |
860 } | |
861 | |
862 IQueryElement ConvertInternal(IQueryElement element, ConvertFunc action) | |
863 { | |
864 if (element == null) | |
865 return null; | |
866 | |
867 IQueryElement newElement; | |
868 | |
869 if (_visitedElements.TryGetValue(element, out newElement)) | |
870 return newElement; | |
871 | |
872 switch (element.ElementType) | |
873 { | |
874 case QueryElementType.SqlFunction: | |
875 { | |
876 var func = (SqlFunction)element; | |
877 var parms = Convert(func.Parameters, action); | |
878 | |
879 if (parms != null && !ReferenceEquals(parms, func.Parameters)) | |
880 newElement = new SqlFunction(func.SystemType, func.Name, func.Precedence, parms); | |
881 | |
882 break; | |
883 } | |
884 | |
885 case QueryElementType.SqlExpression: | |
886 { | |
887 var expr = (SqlExpression)element; | |
888 var parameter = Convert(expr.Parameters, action); | |
889 | |
890 if (parameter != null && !ReferenceEquals(parameter, expr.Parameters)) | |
891 newElement = new SqlExpression(expr.SystemType, expr.Expr, expr.Precedence, parameter); | |
892 | |
893 break; | |
894 } | |
895 | |
896 case QueryElementType.SqlBinaryExpression: | |
897 { | |
898 var bexpr = (SqlBinaryExpression)element; | |
899 var expr1 = (ISqlExpression)ConvertInternal(bexpr.Expr1, action); | |
900 var expr2 = (ISqlExpression)ConvertInternal(bexpr.Expr2, action); | |
901 | |
902 if (expr1 != null && !ReferenceEquals(expr1, bexpr.Expr1) || | |
903 expr2 != null && !ReferenceEquals(expr2, bexpr.Expr2)) | |
904 newElement = new SqlBinaryExpression(bexpr.SystemType, expr1 ?? bexpr.Expr1, bexpr.Operation, expr2 ?? bexpr.Expr2, bexpr.Precedence); | |
905 | |
906 break; | |
907 } | |
908 | |
909 case QueryElementType.SqlTable: | |
910 { | |
911 var table = (SqlTable)element; | |
912 var fields1 = ToArray(table.Fields); | |
913 var fields2 = Convert(fields1, action, f => new SqlField(f)); | |
914 var joins = Convert(table.Joins, action, j => j.Clone()); | |
915 var targs = table.TableArguments == null ? null : Convert(table.TableArguments, action); | |
916 | |
917 var fe = fields2 == null || ReferenceEquals(fields1, fields2); | |
918 var je = joins == null || ReferenceEquals(table.Joins, joins); | |
919 var ta = ReferenceEquals(table.TableArguments, targs); | |
920 | |
921 if (!fe || !je || !ta) | |
922 { | |
923 if (fe) | |
924 { | |
925 fields2 = fields1; | |
926 | |
927 for (var i = 0; i < fields2.Length; i++) | |
928 { | |
929 var field = fields2[i]; | |
930 | |
931 fields2[i] = new SqlField(field); | |
932 | |
933 _visitedElements[field] = fields2[i]; | |
934 } | |
935 } | |
936 | |
937 newElement = new SqlTable(table, fields2, joins ?? table.Joins, targs ?? table.TableArguments); | |
938 | |
939 _visitedElements[((SqlTable)newElement).All] = table.All; | |
940 } | |
941 | |
942 break; | |
943 } | |
944 | |
945 case QueryElementType.Join: | |
946 { | |
947 var join = (Join)element; | |
948 var ons = Convert(join.JoinOns, action); | |
949 | |
950 if (ons != null && !ReferenceEquals(join.JoinOns, ons)) | |
951 newElement = new Join(join.TableName, join.Alias, ons); | |
952 | |
953 break; | |
954 } | |
955 | |
956 case QueryElementType.Column: | |
957 { | |
958 var col = (SqlQuery.Column)element; | |
959 var expr = (ISqlExpression)ConvertInternal(col.Expression, action); | |
960 | |
961 IQueryElement parent; | |
962 _visitedElements.TryGetValue(col.Parent, out parent); | |
963 | |
964 if (parent != null || expr != null && !ReferenceEquals(expr, col.Expression)) | |
965 newElement = new SqlQuery.Column(parent == null ? col.Parent : (SqlQuery)parent, expr ?? col.Expression, col._alias); | |
966 | |
967 break; | |
968 } | |
969 | |
970 case QueryElementType.TableSource: | |
971 { | |
972 var table = (SqlQuery.TableSource)element; | |
973 var source = (ISqlTableSource)ConvertInternal(table.Source, action); | |
974 var joins = Convert(table.Joins, action); | |
975 | |
976 if (source != null && !ReferenceEquals(source, table.Source) || | |
977 joins != null && !ReferenceEquals(table.Joins, joins)) | |
978 newElement = new SqlQuery.TableSource(source ?? table.Source, table._alias, joins ?? table.Joins); | |
979 | |
980 break; | |
981 } | |
982 | |
983 case QueryElementType.JoinedTable: | |
984 { | |
985 var join = (SqlQuery.JoinedTable)element; | |
986 var table = (SqlQuery.TableSource) ConvertInternal(join.Table, action); | |
987 var cond = (SqlQuery.SearchCondition)ConvertInternal(join.Condition, action); | |
988 | |
989 if (table != null && !ReferenceEquals(table, join.Table) || | |
990 cond != null && !ReferenceEquals(cond, join.Condition)) | |
991 newElement = new SqlQuery.JoinedTable(join.JoinType, table ?? join.Table, join.IsWeak, cond ?? join.Condition); | |
992 | |
993 break; | |
994 } | |
995 | |
996 case QueryElementType.SearchCondition: | |
997 { | |
998 var sc = (SqlQuery.SearchCondition)element; | |
999 var conds = Convert(sc.Conditions, action); | |
1000 | |
1001 if (conds != null && !ReferenceEquals(sc.Conditions, conds)) | |
1002 newElement = new SqlQuery.SearchCondition(conds); | |
1003 | |
1004 break; | |
1005 } | |
1006 | |
1007 case QueryElementType.Condition: | |
1008 { | |
1009 var c = (SqlQuery.Condition)element; | |
1010 var p = (ISqlPredicate)ConvertInternal(c.Predicate, action); | |
1011 | |
1012 if (p != null && !ReferenceEquals(c.Predicate, p)) | |
1013 newElement = new SqlQuery.Condition(c.IsNot, p, c.IsOr); | |
1014 | |
1015 break; | |
1016 } | |
1017 | |
1018 case QueryElementType.ExprPredicate: | |
1019 { | |
1020 var p = (SqlQuery.Predicate.Expr)element; | |
1021 var e = (ISqlExpression)ConvertInternal(p.Expr1, action); | |
1022 | |
1023 if (e != null && !ReferenceEquals(p.Expr1, e)) | |
1024 newElement = new SqlQuery.Predicate.Expr(e, p.Precedence); | |
1025 | |
1026 break; | |
1027 } | |
1028 | |
1029 case QueryElementType.NotExprPredicate: | |
1030 { | |
1031 var p = (SqlQuery.Predicate.NotExpr)element; | |
1032 var e = (ISqlExpression)ConvertInternal(p.Expr1, action); | |
1033 | |
1034 if (e != null && !ReferenceEquals(p.Expr1, e)) | |
1035 newElement = new SqlQuery.Predicate.NotExpr(e, p.IsNot, p.Precedence); | |
1036 | |
1037 break; | |
1038 } | |
1039 | |
1040 case QueryElementType.ExprExprPredicate: | |
1041 { | |
1042 var p = (SqlQuery.Predicate.ExprExpr)element; | |
1043 var e1 = (ISqlExpression)ConvertInternal(p.Expr1, action); | |
1044 var e2 = (ISqlExpression)ConvertInternal(p.Expr2, action); | |
1045 | |
1046 if (e1 != null && !ReferenceEquals(p.Expr1, e1) || e2 != null && !ReferenceEquals(p.Expr2, e2)) | |
1047 newElement = new SqlQuery.Predicate.ExprExpr(e1 ?? p.Expr1, p.Operator, e2 ?? p.Expr2); | |
1048 | |
1049 break; | |
1050 } | |
1051 | |
1052 case QueryElementType.LikePredicate: | |
1053 { | |
1054 var p = (SqlQuery.Predicate.Like)element; | |
1055 var e1 = (ISqlExpression)ConvertInternal(p.Expr1, action); | |
1056 var e2 = (ISqlExpression)ConvertInternal(p.Expr2, action); | |
1057 var es = (ISqlExpression)ConvertInternal(p.Escape, action); | |
1058 | |
1059 if (e1 != null && !ReferenceEquals(p.Expr1, e1) || | |
1060 e2 != null && !ReferenceEquals(p.Expr2, e2) || | |
1061 es != null && !ReferenceEquals(p.Escape, es)) | |
1062 newElement = new SqlQuery.Predicate.Like(e1 ?? p.Expr1, p.IsNot, e2 ?? p.Expr2, es ?? p.Escape); | |
1063 | |
1064 break; | |
1065 } | |
1066 | |
1067 case QueryElementType.BetweenPredicate: | |
1068 { | |
1069 var p = (SqlQuery.Predicate.Between)element; | |
1070 var e1 = (ISqlExpression)ConvertInternal(p.Expr1, action); | |
1071 var e2 = (ISqlExpression)ConvertInternal(p.Expr2, action); | |
1072 var e3 = (ISqlExpression)ConvertInternal(p.Expr3, action); | |
1073 | |
1074 if (e1 != null && !ReferenceEquals(p.Expr1, e1) || | |
1075 e2 != null && !ReferenceEquals(p.Expr2, e2) || | |
1076 e3 != null && !ReferenceEquals(p.Expr3, e3)) | |
1077 newElement = new SqlQuery.Predicate.Between(e1 ?? p.Expr1, p.IsNot, e2 ?? p.Expr2, e3 ?? p.Expr3); | |
1078 | |
1079 break; | |
1080 } | |
1081 | |
1082 case QueryElementType.IsNullPredicate: | |
1083 { | |
1084 var p = (SqlQuery.Predicate.IsNull)element; | |
1085 var e = (ISqlExpression)ConvertInternal(p.Expr1, action); | |
1086 | |
1087 if (e != null && !ReferenceEquals(p.Expr1, e)) | |
1088 newElement = new SqlQuery.Predicate.IsNull(e, p.IsNot); | |
1089 | |
1090 break; | |
1091 } | |
1092 | |
1093 case QueryElementType.InSubQueryPredicate: | |
1094 { | |
1095 var p = (SqlQuery.Predicate.InSubQuery)element; | |
1096 var e = (ISqlExpression)ConvertInternal(p.Expr1, action); | |
1097 var q = (SqlQuery)ConvertInternal(p.SubQuery, action); | |
1098 | |
1099 if (e != null && !ReferenceEquals(p.Expr1, e) || q != null && !ReferenceEquals(p.SubQuery, q)) | |
1100 newElement = new SqlQuery.Predicate.InSubQuery(e ?? p.Expr1, p.IsNot, q ?? p.SubQuery); | |
1101 | |
1102 break; | |
1103 } | |
1104 | |
1105 case QueryElementType.InListPredicate: | |
1106 { | |
1107 var p = (SqlQuery.Predicate.InList)element; | |
1108 var e = (ISqlExpression)ConvertInternal(p.Expr1, action); | |
1109 var v = Convert(p.Values, action); | |
1110 | |
1111 if (e != null && !ReferenceEquals(p.Expr1, e) || v != null && !ReferenceEquals(p.Values, v)) | |
1112 newElement = new SqlQuery.Predicate.InList(e ?? p.Expr1, p.IsNot, v ?? p.Values); | |
1113 | |
1114 break; | |
1115 } | |
1116 | |
1117 case QueryElementType.FuncLikePredicate: | |
1118 { | |
1119 var p = (SqlQuery.Predicate.FuncLike)element; | |
1120 var f = (SqlFunction)ConvertInternal(p.Function, action); | |
1121 | |
1122 if (f != null && !ReferenceEquals(p.Function, f)) | |
1123 newElement = new SqlQuery.Predicate.FuncLike(f); | |
1124 | |
1125 break; | |
1126 } | |
1127 | |
1128 case QueryElementType.SetExpression: | |
1129 { | |
1130 var s = (SqlQuery.SetExpression)element; | |
1131 var c = (ISqlExpression)ConvertInternal(s.Column, action); | |
1132 var e = (ISqlExpression)ConvertInternal(s.Expression, action); | |
1133 | |
1134 if (c != null && !ReferenceEquals(s.Column, c) || e != null && !ReferenceEquals(s.Expression, e)) | |
1135 newElement = new SqlQuery.SetExpression(c ?? s.Column, e ?? s.Expression); | |
1136 | |
1137 break; | |
1138 } | |
1139 | |
1140 case QueryElementType.InsertClause: | |
1141 { | |
1142 var s = (SqlQuery.InsertClause)element; | |
1143 var t = s.Into != null ? (SqlTable)ConvertInternal(s.Into, action) : null; | |
1144 var i = Convert(s.Items, action); | |
1145 | |
1146 if (t != null && !ReferenceEquals(s.Into, t) || i != null && !ReferenceEquals(s.Items, i)) | |
1147 { | |
1148 var sc = new SqlQuery.InsertClause { Into = t ?? s.Into }; | |
1149 | |
1150 sc.Items.AddRange(i ?? s.Items); | |
1151 sc.WithIdentity = s.WithIdentity; | |
1152 | |
1153 newElement = sc; | |
1154 } | |
1155 | |
1156 break; | |
1157 } | |
1158 | |
1159 case QueryElementType.UpdateClause: | |
1160 { | |
1161 var s = (SqlQuery.UpdateClause)element; | |
1162 var t = s.Table != null ? (SqlTable)ConvertInternal(s.Table, action) : null; | |
1163 var i = Convert(s.Items, action); | |
1164 var k = Convert(s.Keys, action); | |
1165 | |
1166 if (t != null && !ReferenceEquals(s.Table, t) || | |
1167 i != null && !ReferenceEquals(s.Items, i) || | |
1168 k != null && !ReferenceEquals(s.Keys, k)) | |
1169 { | |
1170 var sc = new SqlQuery.UpdateClause { Table = t ?? s.Table }; | |
1171 | |
1172 sc.Items.AddRange(i ?? s.Items); | |
1173 sc.Keys. AddRange(k ?? s.Keys); | |
1174 | |
1175 newElement = sc; | |
1176 } | |
1177 | |
1178 break; | |
1179 } | |
1180 | |
1181 case QueryElementType.DeleteClause: | |
1182 { | |
1183 var s = (SqlQuery.DeleteClause)element; | |
1184 var t = s.Table != null ? (SqlTable)ConvertInternal(s.Table, action) : null; | |
1185 | |
1186 if (t != null && !ReferenceEquals(s.Table, t)) | |
1187 { | |
1188 newElement = new SqlQuery.DeleteClause { Table = t ?? s.Table }; | |
1189 } | |
1190 | |
1191 break; | |
1192 } | |
1193 | |
1194 case QueryElementType.SelectClause: | |
1195 { | |
1196 var sc = (SqlQuery.SelectClause)element; | |
1197 var cols = Convert(sc.Columns, action); | |
1198 var take = (ISqlExpression)ConvertInternal(sc.TakeValue, action); | |
1199 var skip = (ISqlExpression)ConvertInternal(sc.SkipValue, action); | |
1200 | |
1201 IQueryElement parent; | |
1202 _visitedElements.TryGetValue(sc.SqlQuery, out parent); | |
1203 | |
1204 if (parent != null || | |
1205 cols != null && !ReferenceEquals(sc.Columns, cols) || | |
1206 take != null && !ReferenceEquals(sc.TakeValue, take) || | |
1207 skip != null && !ReferenceEquals(sc.SkipValue, skip)) | |
1208 { | |
1209 newElement = new SqlQuery.SelectClause(sc.IsDistinct, take ?? sc.TakeValue, skip ?? sc.SkipValue, cols ?? sc.Columns); | |
1210 ((SqlQuery.SelectClause)newElement).SetSqlQuery((SqlQuery)parent); | |
1211 } | |
1212 | |
1213 break; | |
1214 } | |
1215 | |
1216 case QueryElementType.FromClause: | |
1217 { | |
1218 var fc = (SqlQuery.FromClause)element; | |
1219 var ts = Convert(fc.Tables, action); | |
1220 | |
1221 IQueryElement parent; | |
1222 _visitedElements.TryGetValue(fc.SqlQuery, out parent); | |
1223 | |
1224 if (parent != null || ts != null && !ReferenceEquals(fc.Tables, ts)) | |
1225 { | |
1226 newElement = new SqlQuery.FromClause(ts ?? fc.Tables); | |
1227 ((SqlQuery.FromClause)newElement).SetSqlQuery((SqlQuery)parent); | |
1228 } | |
1229 | |
1230 break; | |
1231 } | |
1232 | |
1233 case QueryElementType.WhereClause: | |
1234 { | |
1235 var wc = (SqlQuery.WhereClause)element; | |
1236 var cond = (SqlQuery.SearchCondition)ConvertInternal(wc.SearchCondition, action); | |
1237 | |
1238 IQueryElement parent; | |
1239 _visitedElements.TryGetValue(wc.SqlQuery, out parent); | |
1240 | |
1241 if (parent != null || cond != null && !ReferenceEquals(wc.SearchCondition, cond)) | |
1242 { | |
1243 newElement = new SqlQuery.WhereClause(cond ?? wc.SearchCondition); | |
1244 ((SqlQuery.WhereClause)newElement).SetSqlQuery((SqlQuery)parent); | |
1245 } | |
1246 | |
1247 break; | |
1248 } | |
1249 | |
1250 case QueryElementType.GroupByClause: | |
1251 { | |
1252 var gc = (SqlQuery.GroupByClause)element; | |
1253 var es = Convert(gc.Items, action); | |
1254 | |
1255 IQueryElement parent; | |
1256 _visitedElements.TryGetValue(gc.SqlQuery, out parent); | |
1257 | |
1258 if (parent != null || es != null && !ReferenceEquals(gc.Items, es)) | |
1259 { | |
1260 newElement = new SqlQuery.GroupByClause(es ?? gc.Items); | |
1261 ((SqlQuery.GroupByClause)newElement).SetSqlQuery((SqlQuery)parent); | |
1262 } | |
1263 | |
1264 break; | |
1265 } | |
1266 | |
1267 case QueryElementType.OrderByClause: | |
1268 { | |
1269 var oc = (SqlQuery.OrderByClause)element; | |
1270 var es = Convert(oc.Items, action); | |
1271 | |
1272 IQueryElement parent; | |
1273 _visitedElements.TryGetValue(oc.SqlQuery, out parent); | |
1274 | |
1275 if (parent != null || es != null && !ReferenceEquals(oc.Items, es)) | |
1276 { | |
1277 newElement = new SqlQuery.OrderByClause(es ?? oc.Items); | |
1278 ((SqlQuery.OrderByClause)newElement).SetSqlQuery((SqlQuery)parent); | |
1279 } | |
1280 | |
1281 break; | |
1282 } | |
1283 | |
1284 case QueryElementType.OrderByItem: | |
1285 { | |
1286 var i = (SqlQuery.OrderByItem)element; | |
1287 var e = (ISqlExpression)ConvertInternal(i.Expression, action); | |
1288 | |
1289 if (e != null && !ReferenceEquals(i.Expression, e)) | |
1290 newElement = new SqlQuery.OrderByItem(e, i.IsDescending); | |
1291 | |
1292 break; | |
1293 } | |
1294 | |
1295 case QueryElementType.Union: | |
1296 { | |
1297 var u = (SqlQuery.Union)element; | |
1298 var q = (SqlQuery)ConvertInternal(u.SqlQuery, action); | |
1299 | |
1300 if (q != null && !ReferenceEquals(u.SqlQuery, q)) | |
1301 newElement = new SqlQuery.Union(q, u.IsAll); | |
1302 | |
1303 break; | |
1304 } | |
1305 | |
1306 case QueryElementType.SqlQuery: | |
1307 { | |
1308 var q = (SqlQuery)element; | |
1309 IQueryElement parent = null; | |
1310 | |
1311 var doConvert = q.ParentSql != null && !_visitedElements.TryGetValue(q.ParentSql, out parent); | |
1312 | |
1313 if (!doConvert) | |
1314 { | |
1315 doConvert = null != Find(q, e => | |
1316 { | |
1317 if (_visitedElements.ContainsKey(e) && _visitedElements[e] != e) | |
1318 return true; | |
1319 | |
1320 var ret = action(e); | |
1321 | |
1322 if (ret != null && !ReferenceEquals(e, ret)) | |
1323 { | |
1324 _visitedElements.Add(e, ret); | |
1325 return true; | |
1326 } | |
1327 | |
1328 return false; | |
1329 }); | |
1330 } | |
1331 | |
1332 if (!doConvert) | |
1333 break; | |
1334 | |
1335 var nq = new SqlQuery { QueryType = q.QueryType }; | |
1336 | |
1337 _visitedElements.Add(q, nq); | |
1338 | |
1339 var fc = (SqlQuery.FromClause) ConvertInternal(q.From, action) ?? q.From; | |
1340 var sc = (SqlQuery.SelectClause) ConvertInternal(q.Select, action) ?? q.Select; | |
1341 var ic = q.IsInsert ? ((SqlQuery.InsertClause)ConvertInternal(q.Insert, action) ?? q.Insert) : null; | |
1342 var uc = q.IsUpdate ? ((SqlQuery.UpdateClause)ConvertInternal(q.Update, action) ?? q.Update) : null; | |
1343 var dc = q.IsDelete ? ((SqlQuery.DeleteClause)ConvertInternal(q.Delete, action) ?? q.Delete) : null; | |
1344 var wc = (SqlQuery.WhereClause) ConvertInternal(q.Where, action) ?? q.Where; | |
1345 var gc = (SqlQuery.GroupByClause)ConvertInternal(q.GroupBy, action) ?? q.GroupBy; | |
1346 var hc = (SqlQuery.WhereClause) ConvertInternal(q.Having, action) ?? q.Having; | |
1347 var oc = (SqlQuery.OrderByClause)ConvertInternal(q.OrderBy, action) ?? q.OrderBy; | |
1348 var us = q.HasUnion ? Convert(q.Unions, action) : q.Unions; | |
1349 | |
1350 var ps = new List<SqlParameter>(q.Parameters.Count); | |
1351 | |
1352 foreach (var p in q.Parameters) | |
1353 { | |
1354 IQueryElement e; | |
1355 | |
1356 if (_visitedElements.TryGetValue(p, out e)) | |
1357 { | |
1358 if (e == null) | |
1359 ps.Add(p); | |
1360 else if (e is SqlParameter) | |
1361 ps.Add((SqlParameter)e); | |
1362 } | |
1363 } | |
1364 | |
1365 nq.Init(ic, uc, dc, sc, fc, wc, gc, hc, oc, us, (SqlQuery)parent, q.IsParameterDependent, ps); | |
1366 | |
1367 _visitedElements[q] = action(nq) ?? nq; | |
1368 | |
1369 return nq; | |
1370 } | |
1371 } | |
1372 | |
1373 newElement = newElement == null ? action(element) : (action(newElement) ?? newElement); | |
1374 | |
1375 _visitedElements.Add(element, newElement); | |
1376 | |
1377 return newElement; | |
1378 } | |
1379 | |
1380 static TE[] ToArray<TK,TE>(IDictionary<TK,TE> dic) | |
1381 { | |
1382 var es = new TE[dic.Count]; | |
1383 var i = 0; | |
1384 | |
1385 foreach (var e in dic.Values) | |
1386 es[i++] = e; | |
1387 | |
1388 return es; | |
1389 } | |
1390 | |
1391 delegate T Clone<T>(T obj); | |
1392 | |
1393 T[] Convert<T>(T[] arr, ConvertFunc action) | |
1394 where T : class, IQueryElement | |
1395 { | |
1396 return Convert(arr, action, null); | |
1397 } | |
1398 | |
1399 T[] Convert<T>(T[] arr1, ConvertFunc action, Clone<T> clone) | |
1400 where T : class, IQueryElement | |
1401 { | |
1402 T[] arr2 = null; | |
1403 | |
1404 for (var i = 0; i < arr1.Length; i++) | |
1405 { | |
1406 var elem1 = arr1[i]; | |
1407 var elem2 = (T)ConvertInternal(elem1, action); | |
1408 | |
1409 if (elem2 != null && !ReferenceEquals(elem1, elem2)) | |
1410 { | |
1411 if (arr2 == null) | |
1412 { | |
1413 arr2 = new T[arr1.Length]; | |
1414 | |
1415 for (var j = 0; j < i; j++) | |
1416 arr2[j] = clone == null ? arr1[j] : clone(arr1[j]); | |
1417 } | |
1418 | |
1419 arr2[i] = elem2; | |
1420 } | |
1421 else if (arr2 != null) | |
1422 arr2[i] = clone == null ? elem1 : clone(elem1); | |
1423 } | |
1424 | |
1425 return arr2; | |
1426 } | |
1427 | |
1428 List<T> Convert<T>(List<T> list, ConvertFunc action) | |
1429 where T : class, IQueryElement | |
1430 { | |
1431 return Convert(list, action, null); | |
1432 } | |
1433 | |
1434 List<T> Convert<T>(List<T> list1, ConvertFunc action, Clone<T> clone) | |
1435 where T : class, IQueryElement | |
1436 { | |
1437 List<T> list2 = null; | |
1438 | |
1439 for (var i = 0; i < list1.Count; i++) | |
1440 { | |
1441 var elem1 = list1[i]; | |
1442 var elem2 = (T)ConvertInternal(elem1, action); | |
1443 | |
1444 if (elem2 != null && !ReferenceEquals(elem1, elem2)) | |
1445 { | |
1446 if (list2 == null) | |
1447 { | |
1448 list2 = new List<T>(list1.Count); | |
1449 | |
1450 for (var j = 0; j < i; j++) | |
1451 list2.Add(clone == null ? list1[j] : clone(list1[j])); | |
1452 } | |
1453 | |
1454 list2.Add(elem2); | |
1455 } | |
1456 else if (list2 != null) | |
1457 list2.Add(clone == null ? elem1 : clone(elem1)); | |
1458 } | |
1459 | |
1460 return list2; | |
1461 } | |
1462 | |
1463 #endregion | |
1464 } | |
1465 } |