annotate Source/Data/Linq/Builder/ExpressionBuilder.QueryBuilder.cs @ 2:79a04c6442bf

file name case fix
author cin
date Fri, 22 Aug 2014 13:41:57 +0400
parents f990fcb411a9
children 1ef98bd70424
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1 using System;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2 using System.Collections;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
3 using System.Collections.Generic;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
4 using System.Data;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
5 using System.Linq;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
6 using System.Linq.Expressions;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
7 using System.Reflection;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
8
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
9 namespace BLToolkit.Data.Linq.Builder
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
10 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
11 using BLToolkit.Linq;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
12 using Reflection;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
13
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
14 partial class ExpressionBuilder
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
15 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
16 #region BuildExpression
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
17
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
18 readonly HashSet<Expression> _skippedExpressions = new HashSet<Expression>();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
19
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
20 public Expression BuildExpression(IBuildContext context, Expression expression)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
21 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
22 var newExpr = expression.Convert2(expr =>
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
23 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
24 if (_skippedExpressions.Contains(expr))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
25 return new ExpressionHelper.ConvertInfo(expr, true);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
26
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
27 if (expr.Find(IsNoneSqlMember) != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
28 return new ExpressionHelper.ConvertInfo(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
29
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
30 switch (expr.NodeType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
31 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
32 case ExpressionType.MemberAccess:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
33 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
34 if (IsServerSideOnly(expr) || PreferServerSide(expr))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
35 return new ExpressionHelper.ConvertInfo(BuildSql(context, expr));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
36
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
37 var ma = (MemberExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
38
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
39 if (SqlProvider.ConvertMember(ma.Member) != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
40 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
41
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
42 var ctx = GetContext(context, expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
43
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
44 if (ctx != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
45 return new ExpressionHelper.ConvertInfo(ctx.BuildExpression(expr, 0));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
46
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
47 var ex = ma.Expression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
48
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
49 if (ex != null && ex.NodeType == ExpressionType.Constant)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
50 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
51 // field = localVariable
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
52 //
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
53 var c = _expressionAccessors[ex];
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
54 return new ExpressionHelper.ConvertInfo(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
55 Expression.MakeMemberAccess(Expression.Convert(c, ex.Type), ma.Member));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
56 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
57
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
58 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
59 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
60
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
61 case ExpressionType.Parameter:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
62 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
63 if (expr == ParametersParam)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
64 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
65
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
66 var ctx = GetContext(context, expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
67
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
68 if (ctx != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
69 return new ExpressionHelper.ConvertInfo(ctx.BuildExpression(expr, 0));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
70
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
71 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
72 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
73
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
74 case ExpressionType.Constant:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
75 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
76 if (ExpressionHelper.IsConstant(expr.Type))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
77 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
78
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
79 if (_expressionAccessors.ContainsKey(expr))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
80 return new ExpressionHelper.ConvertInfo(Expression.Convert(_expressionAccessors[expr], expr.Type));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
81
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
82 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
83 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
84
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
85 case ExpressionType.Coalesce:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
86
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
87 if (expr.Type == typeof(string) && MappingSchema.GetDefaultNullValue<string>() != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
88 return new ExpressionHelper.ConvertInfo(BuildSql(context, expr));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
89
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
90 if (CanBeTranslatedToSql(context, ConvertExpression(expr), true))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
91 return new ExpressionHelper.ConvertInfo(BuildSql(context, expr));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
92
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
93 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
94
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
95 case ExpressionType.Conditional:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
96
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
97 if (CanBeTranslatedToSql(context, ConvertExpression(expr), true))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
98 return new ExpressionHelper.ConvertInfo(BuildSql(context, expr));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
99 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
100
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
101 case ExpressionType.Call:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
102 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
103 var ce = (MethodCallExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
104
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
105 if (IsGroupJoinSource(context, ce))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
106 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
107 foreach (var arg in ce.Arguments.Skip(1))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
108 if (!_skippedExpressions.Contains(arg))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
109 _skippedExpressions.Add(arg);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
110
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
111 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
112 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
113
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
114 if (IsSubQuery(context, ce))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
115 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
116 if (TypeHelper.IsSameOrParent(typeof(IEnumerable), expr.Type) && expr.Type != typeof(string) && !expr.Type.IsArray)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
117 return new ExpressionHelper.ConvertInfo(BuildMultipleQuery(context, expr));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
118
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
119 return new ExpressionHelper.ConvertInfo(GetSubQuery(context, ce).BuildExpression(null, 0));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
120 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
121
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
122 if (IsServerSideOnly(expr) || PreferServerSide(expr))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
123 return new ExpressionHelper.ConvertInfo(BuildSql(context, expr));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
124 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
125
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
126 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
127 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
128
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
129 if (EnforceServerSide(context))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
130 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
131 switch (expr.NodeType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
132 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
133 case ExpressionType.MemberInit :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
134 case ExpressionType.New :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
135 case ExpressionType.Convert :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
136 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
137
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
138 default :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
139 if (CanBeCompiled(expr))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
140 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
141 return new ExpressionHelper.ConvertInfo(BuildSql(context, expr));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
142 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
143 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
144
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
145 return new ExpressionHelper.ConvertInfo(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
146 });
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
147
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
148 return newExpr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
149 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
150
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
151 static bool EnforceServerSide(IBuildContext context)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
152 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
153 return context.SqlQuery.Select.IsDistinct;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
154 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
155
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
156 #endregion
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
157
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
158 #region BuildSql
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
159
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
160 Expression BuildSql(IBuildContext context, Expression expression)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
161 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
162 var sqlex = ConvertToSqlExpression(context, expression, true);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
163 var idx = context.SqlQuery.Select.Add(sqlex);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
164
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
165 idx = context.ConvertToParentIndex(idx, context);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
166
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
167 var field = BuildSql(expression.Type, idx);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
168
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
169 return field;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
170 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
171
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
172 public Expression BuildSql(MemberAccessor ma, int idx, MethodInfo checkNullFunction, Expression context)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
173 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
174 var expr = Expression.Call(DataReaderParam, ReflectionHelper.DataReader.GetValue, Expression.Constant(idx));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
175
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
176 if (checkNullFunction != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
177 expr = Expression.Call(null, checkNullFunction, expr, context);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
178
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
179 Expression mapper;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
180
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
181 if (TypeHelper.IsEnumOrNullableEnum(ma.Type))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
182 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
183 var type = TypeHelper.ToNullable(ma.Type);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
184 mapper =
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
185 Expression.Convert(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
186 Expression.Call(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
187 Expression.Constant(MappingSchema),
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
188 ReflectionHelper.MapSchema.MapValueToEnumWithMemberAccessor,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
189 expr,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
190 Expression.Constant(ma)),
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
191 type);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
192 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
193 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
194 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
195 MethodInfo mi;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
196
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
197 if (!ReflectionHelper.MapSchema.Converters.TryGetValue(ma.Type, out mi))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
198 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
199 mapper =
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
200 Expression.Convert(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
201 Expression.Call(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
202 Expression.Constant(MappingSchema),
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
203 ReflectionHelper.MapSchema.ChangeType,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
204 expr,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
205 Expression.Constant(ma.Type)),
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
206 ma.Type);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
207 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
208 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
209 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
210 mapper = Expression.Call(Expression.Constant(MappingSchema), mi, expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
211 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
212 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
213
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
214 return mapper;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
215 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
216
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
217 public Expression BuildSql(Type type, int idx, MethodInfo checkNullFunction, Expression context)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
218 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
219 var expr = Expression.Call(DataReaderParam, ReflectionHelper.DataReader.GetValue, Expression.Constant(idx));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
220
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
221 if (checkNullFunction != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
222 expr = Expression.Call(null, checkNullFunction, expr, context);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
223
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
224 Expression mapper;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
225
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
226 if (type.IsEnum)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
227 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
228 mapper =
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
229 Expression.Convert(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
230 Expression.Call(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
231 Expression.Constant(MappingSchema),
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
232 ReflectionHelper.MapSchema.MapValueToEnum,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
233 expr,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
234 Expression.Constant(type)),
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
235 type);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
236 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
237 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
238 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
239 MethodInfo mi;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
240
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
241 if (!ReflectionHelper.MapSchema.Converters.TryGetValue(type, out mi))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
242 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
243 mapper =
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
244 Expression.Convert(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
245 Expression.Call(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
246 Expression.Constant(MappingSchema),
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
247 ReflectionHelper.MapSchema.ChangeType,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
248 expr,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
249 Expression.Constant(type)),
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
250 type);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
251 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
252 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
253 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
254 mapper = Expression.Call(Expression.Constant(MappingSchema), mi, expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
255 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
256 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
257
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
258 return mapper;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
259 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
260
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
261 public Expression BuildSql(Type type, int idx)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
262 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
263 return BuildSql(type, idx, null, null);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
264 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
265
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
266 public Expression BuildSql(MemberAccessor ma, int idx)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
267 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
268 return BuildSql(ma, idx, null, null);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
269 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
270
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
271 #endregion
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
272
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
273 #region IsNonSqlMember
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
274
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
275 bool IsNoneSqlMember(Expression expr)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
276 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
277 switch (expr.NodeType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
278 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
279 case ExpressionType.MemberAccess:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
280 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
281 var me = (MemberExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
282
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
283 var om = (
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
284 from c in Contexts.OfType<TableBuilder.TableContext>()
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
285 where c.ObjectType == me.Member.DeclaringType
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
286 select c.ObjectMapper
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
287 ).FirstOrDefault();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
288
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
289 return om != null && om.Associations.All(a => !TypeHelper.Equals(a.MemberAccessor.MemberInfo, me.Member)) && om[me.Member.Name, true] == null;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
290 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
291 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
292
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
293 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
294 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
295
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
296 #endregion
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
297
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
298 #region PreferServerSide
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
299
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
300 bool PreferServerSide(Expression expr)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
301 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
302 switch (expr.NodeType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
303 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
304 case ExpressionType.MemberAccess:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
305 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
306 var pi = (MemberExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
307 var l = SqlProvider.ConvertMember(pi.Member);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
308
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
309 if (l != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
310 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
311 var info = l.Body.Unwrap();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
312
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
313 if (l.Parameters.Count == 1 && pi.Expression != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
314 info = info.Convert(wpi => wpi == l.Parameters[0] ? pi.Expression : wpi);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
315
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
316 return info.Find(PreferServerSide) != null;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
317 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
318
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
319 var attr = GetFunctionAttribute(pi.Member);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
320 return attr != null && attr.PreferServerSide && !CanBeCompiled(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
321 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
322
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
323 case ExpressionType.Call:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
324 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
325 var pi = (MethodCallExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
326 var e = pi;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
327 var l = SqlProvider.ConvertMember(e.Method);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
328
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
329 if (l != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
330 return l.Body.Unwrap().Find(PreferServerSide) != null;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
331
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
332 var attr = GetFunctionAttribute(e.Method);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
333 return attr != null && attr.PreferServerSide && !CanBeCompiled(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
334 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
335 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
336
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
337 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
338 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
339
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
340 #endregion
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
341
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
342 #region Build Mapper
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
343
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
344 public Expression BuildBlock(Expression expression)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
345 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
346 #if FW4 || SILVERLIGHT
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
347
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
348 if (IsBlockDisable || BlockExpressions.Count == 0)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
349 return expression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
350
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
351 BlockExpressions.Add(expression);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
352
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
353 expression = Expression.Block(BlockVariables, BlockExpressions);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
354
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
355 BlockVariables. Clear();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
356 BlockExpressions.Clear();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
357
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
358 #endif
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
359
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
360 return expression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
361 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
362
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
363 public Expression<Func<QueryContext,IDataContext,IDataReader,Expression,object[],T>> BuildMapper<T>(Expression expr)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
364 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
365 var type = typeof(T);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
366
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
367 if (expr.Type != type)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
368 expr = Expression.Convert(expr, type);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
369
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
370 var mapper = Expression.Lambda<Func<QueryContext,IDataContext,IDataReader,Expression,object[],T>>(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
371 BuildBlock(expr), new []
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
372 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
373 ContextParam,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
374 DataContextParam,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
375 DataReaderParam,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
376 ExpressionParam,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
377 ParametersParam,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
378 });
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
379
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
380 return mapper;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
381 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
382
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
383 #endregion
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
384
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
385 #region BuildMultipleQuery
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
386
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
387 interface IMultipleQueryHelper
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
388 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
389 Expression GetSubquery(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
390 ExpressionBuilder builder,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
391 Expression expression,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
392 ParameterExpression paramArray,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
393 IEnumerable<Expression> parameters);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
394 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
395
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
396 class MultipleQueryHelper<TRet> : IMultipleQueryHelper
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
397 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
398 public Expression GetSubquery(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
399 ExpressionBuilder builder,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
400 Expression expression,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
401 ParameterExpression paramArray,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
402 IEnumerable<Expression> parameters)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
403 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
404 var lambda = Expression.Lambda<Func<IDataContext,object[],TRet>>(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
405 expression,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
406 Expression.Parameter(typeof(IDataContext), "ctx"),
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
407 paramArray);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
408 var queryReader = CompiledQuery.Compile(lambda);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
409
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
410 return Expression.Call(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
411 null,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
412 ReflectionHelper.Expressor<object>.MethodExpressor(_ => ExecuteSubQuery(null, null, null)),
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
413 ContextParam,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
414 Expression.NewArrayInit(typeof(object), parameters),
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
415 Expression.Constant(queryReader)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
416 );
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
417 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
418
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
419 static TRet ExecuteSubQuery(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
420 QueryContext queryContext,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
421 object[] parameters,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
422 Func<IDataContext,object[],TRet> queryReader)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
423 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
424 var db = queryContext.GetDataContext();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
425
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
426 try
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
427 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
428 return queryReader(db.DataContextInfo.DataContext, parameters);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
429 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
430 finally
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
431 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
432 queryContext.ReleaseDataContext(db);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
433 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
434 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
435 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
436
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
437 public Expression BuildMultipleQuery(IBuildContext context, Expression expression)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
438 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
439 if (!Common.Configuration.Linq.AllowMultipleQuery)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
440 throw new LinqException("Multiple queries are not allowed. Set the 'BLToolkit.Common.Configuration.Linq.AllowMultipleQuery' flag to 'true' to allow multiple queries.");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
441
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
442 var parameters = new HashSet<ParameterExpression>();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
443
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
444 expression.Visit(e =>
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
445 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
446 if (e.NodeType == ExpressionType.Lambda)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
447 foreach (var p in ((LambdaExpression)e).Parameters)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
448 parameters.Add(p);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
449 });
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
450
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
451 // Convert associations.
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
452 //
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
453 expression = expression.Convert(e =>
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
454 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
455 switch (e.NodeType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
456 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
457 case ExpressionType.MemberAccess :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
458 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
459 var root = e.GetRootObject();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
460
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
461 if (root != null &&
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
462 root.NodeType == ExpressionType.Parameter &&
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
463 !parameters.Contains((ParameterExpression)root))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
464 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
465 var res = context.IsExpression(e, 0, RequestFor.Association);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
466
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
467 if (res.Result)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
468 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
469 var table = (TableBuilder.AssociatedTableContext)res.Context;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
470
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
471 if (table.IsList)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
472 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
473 var ttype = typeof(Table<>).MakeGenericType(table.ObjectType);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
474 var tbl = Activator.CreateInstance(ttype);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
475 var method = typeof(LinqExtensions)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
476 .GetMethod("Where", BindingFlags.NonPublic | BindingFlags.Static)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
477 .MakeGenericMethod(e.Type, table.ObjectType, ttype);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
478
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
479 var me = (MemberExpression)e;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
480 var op = Expression.Parameter(table.ObjectType, "t");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
481
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
482 parameters.Add(op);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
483
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
484 Expression ex = null;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
485
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
486 for (var i = 0; i < table.Association.ThisKey.Length; i++)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
487 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
488 var field1 = table.ParentAssociation.SqlTable.Fields[table.Association.ThisKey [i]];
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
489 var field2 = table. SqlTable.Fields[table.Association.OtherKey[i]];
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
490
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
491 var ee = Expression.Equal(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
492 Expression.MakeMemberAccess(op, field2.MemberMapper.MemberAccessor.MemberInfo),
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
493 Expression.MakeMemberAccess(me.Expression, field1.MemberMapper.MemberAccessor.MemberInfo));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
494
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
495 ex = ex == null ? ee : Expression.AndAlso(ex, ee);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
496 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
497
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
498 return Expression.Call(null, method, Expression.Constant(tbl), Expression.Lambda(ex, op));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
499 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
500 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
501 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
502
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
503 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
504 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
505 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
506
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
507 return e;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
508 });
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
509
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
510 var paramex = Expression.Parameter(typeof(object[]), "ps");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
511 var parms = new List<Expression>();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
512
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
513 // Convert parameters.
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
514 //
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
515 expression = expression.Convert(e =>
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
516 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
517 var root = e.GetRootObject();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
518
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
519 if (root != null &&
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
520 root.NodeType == ExpressionType.Parameter &&
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
521 !parameters.Contains((ParameterExpression)root))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
522 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
523 var ex = Expression.Convert(BuildExpression(context, e), typeof(object));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
524
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
525 parms.Add(ex);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
526
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
527 return Expression.Convert(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
528 Expression.ArrayIndex(paramex, Expression.Constant(parms.Count - 1)),
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
529 e.Type);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
530 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
531
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
532 return e;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
533 });
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
534
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
535 var sqtype = typeof(MultipleQueryHelper<>).MakeGenericType(expression.Type);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
536 var helper = (IMultipleQueryHelper)Activator.CreateInstance(sqtype);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
537
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
538 return helper.GetSubquery(this, expression, paramex, parms);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
539 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
540
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
541 #endregion
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
542 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
543 }