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 }