0
|
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 }
|