Mercurial > pub > bltoolkit
comparison Source/Data/Linq/Builder/AllAnyBuilder.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.Expressions; | |
3 | |
4 namespace BLToolkit.Data.Linq.Builder | |
5 { | |
6 using BLToolkit.Linq; | |
7 using Data.Sql; | |
8 | |
9 class AllAnyBuilder : MethodCallBuilder | |
10 { | |
11 protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) | |
12 { | |
13 return methodCall.IsQueryable("All", "Any"); | |
14 } | |
15 | |
16 protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) | |
17 { | |
18 var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0]) { CopyTable = true }); | |
19 | |
20 if (methodCall.Arguments.Count == 2) | |
21 { | |
22 var condition = (LambdaExpression)methodCall.Arguments[1].Unwrap(); | |
23 | |
24 if (methodCall.Method.Name == "All") | |
25 #if FW4 || SILVERLIGHT | |
26 condition = Expression.Lambda(Expression.Not(condition.Body), condition.Name, condition.Parameters); | |
27 #else | |
28 condition = Expression.Lambda(Expression.Not(condition.Body), condition.Parameters.ToArray()); | |
29 #endif | |
30 | |
31 sequence = builder.BuildWhere(buildInfo.Parent, sequence, condition, true); | |
32 sequence.SetAlias(condition.Parameters[0].Name); | |
33 } | |
34 | |
35 return new AllAnyContext(buildInfo.Parent, methodCall, sequence); | |
36 } | |
37 | |
38 protected override SequenceConvertInfo Convert( | |
39 ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo, ParameterExpression param) | |
40 { | |
41 if (methodCall.Arguments.Count == 2) | |
42 { | |
43 var predicate = (LambdaExpression)methodCall.Arguments[1].Unwrap(); | |
44 var info = builder.ConvertSequence(new BuildInfo(buildInfo, methodCall.Arguments[0]), predicate.Parameters[0]); | |
45 | |
46 if (info != null) | |
47 { | |
48 info.Expression = methodCall.Convert(ex => ConvertMethod(methodCall, 0, info, predicate.Parameters[0], ex)); | |
49 info.Parameter = param; | |
50 | |
51 return info; | |
52 } | |
53 } | |
54 else | |
55 { | |
56 var info = builder.ConvertSequence(new BuildInfo(buildInfo, methodCall.Arguments[0]), null); | |
57 | |
58 if (info != null) | |
59 { | |
60 info.Expression = methodCall.Convert(ex => ConvertMethod(methodCall, 0, info, null, ex)); | |
61 info.Parameter = param; | |
62 | |
63 return info; | |
64 } | |
65 } | |
66 | |
67 return null; | |
68 } | |
69 | |
70 class AllAnyContext : SequenceContextBase | |
71 { | |
72 readonly MethodCallExpression _methodCall; | |
73 | |
74 public AllAnyContext(IBuildContext parent, MethodCallExpression methodCall, IBuildContext sequence) | |
75 : base(parent, sequence, null) | |
76 { | |
77 _methodCall = methodCall; | |
78 } | |
79 | |
80 public override void BuildQuery<T>(Query<T> query, ParameterExpression queryParameter) | |
81 { | |
82 var sql = GetSubQuery(null); | |
83 | |
84 query.Queries[0].SqlQuery = new SqlQuery(); | |
85 query.Queries[0].SqlQuery.Select.Add(sql); | |
86 | |
87 var expr = Builder.BuildSql(typeof(bool), 0); | |
88 var mapper = Builder.BuildMapper<object>(expr); | |
89 | |
90 query.SetElementQuery(mapper.Compile()); | |
91 } | |
92 | |
93 public override Expression BuildExpression(Expression expression, int level) | |
94 { | |
95 var idx = ConvertToIndex(expression, level, ConvertFlags.Field); | |
96 return Builder.BuildSql(typeof(bool), idx[0].Index); | |
97 } | |
98 | |
99 public override SqlInfo[] ConvertToSql(Expression expression, int level, ConvertFlags flags) | |
100 { | |
101 if (expression == null) | |
102 { | |
103 var sql = GetSubQuery(null); | |
104 var query = SqlQuery; | |
105 | |
106 if (Parent != null) | |
107 query = Parent.SqlQuery; | |
108 | |
109 return new[] { new SqlInfo { Query = query, Sql = sql } }; | |
110 } | |
111 | |
112 throw new InvalidOperationException(); | |
113 } | |
114 | |
115 public override SqlInfo[] ConvertToIndex(Expression expression, int level, ConvertFlags flags) | |
116 { | |
117 var sql = ConvertToSql(expression, level, flags); | |
118 | |
119 if (sql[0].Index < 0) | |
120 sql[0].Index = sql[0].Query.Select.Add(sql[0].Sql); | |
121 | |
122 return sql; | |
123 } | |
124 | |
125 public override IsExpressionResult IsExpression(Expression expression, int level, RequestFor requestFlag) | |
126 { | |
127 if (expression == null) | |
128 { | |
129 switch (requestFlag) | |
130 { | |
131 case RequestFor.Expression : | |
132 case RequestFor.Field : return IsExpressionResult.False; | |
133 } | |
134 } | |
135 | |
136 throw new InvalidOperationException(); | |
137 } | |
138 | |
139 public override IBuildContext GetContext(Expression expression, int level, BuildInfo buildInfo) | |
140 { | |
141 throw new InvalidOperationException(); | |
142 } | |
143 | |
144 ISqlExpression _subQuerySql; | |
145 | |
146 public override ISqlExpression GetSubQuery(IBuildContext context) | |
147 { | |
148 if (_subQuerySql == null) | |
149 { | |
150 var cond = new SqlQuery.Condition( | |
151 _methodCall.Method.Name == "All", | |
152 new SqlQuery.Predicate.FuncLike(SqlFunction.CreateExists(SqlQuery))); | |
153 | |
154 _subQuerySql = new SqlQuery.SearchCondition(cond); | |
155 } | |
156 | |
157 return _subQuerySql; | |
158 } | |
159 } | |
160 } | |
161 } |