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