annotate Source/Data/Linq/Builder/ConcatUnionBuilder.cs @ 9:1e85f66cf767 default tip

update bltoolkit
author nickolay
date Thu, 05 Apr 2018 20:53:26 +0300
parents f990fcb411a9
children
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.Generic;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
3 using System.Linq;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
4 using System.Linq.Expressions;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
5 using System.Reflection;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
6
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
7 namespace BLToolkit.Data.Linq.Builder
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
8 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
9 using BLToolkit.Linq;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
10 using Data.Sql;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
11 using Reflection;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
12
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
13 class ConcatUnionBuilder : MethodCallBuilder
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
14 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
15 #region Builder
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
16
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
17 protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
18 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
19 return methodCall.Arguments.Count == 2 && methodCall.IsQueryable("Concat", "Union");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
20 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
21
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
22 protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
23 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
24 var sequence1 = new SubQueryContext(builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
25 var sequence2 = new SubQueryContext(builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[1], new SqlQuery())));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
26 var union = new SqlQuery.Union(sequence2.SqlQuery, methodCall.Method.Name == "Concat");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
27
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
28 sequence1.SqlQuery.Unions.Add(union);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
29
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
30 return new UnionContext(sequence1, sequence2, methodCall);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
31 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
32
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
33 protected override SequenceConvertInfo Convert(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
34 ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo, ParameterExpression param)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
35 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
36 return null;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
37 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
38
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
39 #endregion
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
40
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
41 #region Context
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
42
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
43 sealed class UnionContext : SubQueryContext
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
44 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
45 public UnionContext(SubQueryContext sequence1, SubQueryContext sequence2, MethodCallExpression methodCall)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
46 : base(sequence1)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
47 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
48 _methodCall = methodCall;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
49
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
50 _isObject =
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
51 sequence1.IsExpression(null, 0, RequestFor.Object).Result ||
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
52 sequence2.IsExpression(null, 0, RequestFor.Object).Result;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
53
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
54 if (_isObject)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
55 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
56 var type = _methodCall.Method.GetGenericArguments()[0];
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
57 _unionParameter = Expression.Parameter(type, "t");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
58 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
59
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
60 Init(sequence1, sequence2);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
61 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
62
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
63 readonly bool _isObject;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
64 readonly MethodCallExpression _methodCall;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
65 readonly ParameterExpression _unionParameter;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
66 readonly Dictionary<MemberInfo,Member> _members = new Dictionary<MemberInfo,Member>(new MemberInfoComparer());
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
67
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
68 class Member
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
69 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
70 public SqlInfo SequenceInfo;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
71 public SqlInfo SqlQueryInfo;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
72 public MemberExpression MemberExpression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
73 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
74
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
75 class UnionMember
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
76 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
77 public Member Member;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
78 public SqlInfo Info1;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
79 public SqlInfo Info2;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
80 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
81
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
82 void Init(SubQueryContext sequence1, SubQueryContext sequence2)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
83 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
84 var info1 = sequence1.ConvertToIndex(null, 0, ConvertFlags.All).ToList();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
85 var info2 = sequence2.ConvertToIndex(null, 0, ConvertFlags.All).ToList();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
86
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
87 if (!_isObject)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
88 return;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
89
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
90 var members = new List<UnionMember>();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
91
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
92 foreach (var info in info1)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
93 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
94 if (info.Members.Count == 0)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
95 throw new InvalidOperationException();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
96
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
97 var member = new Member
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
98 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
99 SequenceInfo = info,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
100 MemberExpression = Expression.MakeMemberAccess(_unionParameter, info.Members[0])
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
101 };
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
102
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
103 members.Add(new UnionMember { Member = member, Info1 = info });
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
104 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
105
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
106 foreach (var info in info2)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
107 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
108 if (info.Members.Count == 0)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
109 throw new InvalidOperationException();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
110
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
111 var em = members.FirstOrDefault(m =>
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
112 m.Member.SequenceInfo != null &&
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
113 m.Member.SequenceInfo.CompareLastMember(info));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
114
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
115 if (em == null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
116 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
117 var member = new Member { MemberExpression = Expression.MakeMemberAccess(_unionParameter, info.Members[0]) };
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
118
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
119 if (sequence2.IsExpression(member.MemberExpression, 1, RequestFor.Object).Result)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
120 throw new LinqException("Types in {0} are constructed incompatibly.", _methodCall.Method.Name);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
121
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
122 members.Add(new UnionMember { Member = member, Info2 = info });
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
123 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
124 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
125 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
126 em.Info2 = info;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
127 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
128 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
129
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
130 sequence1.SqlQuery.Select.Columns.Clear();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
131 sequence2.SqlQuery.Select.Columns.Clear();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
132
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
133 for (var i = 0; i < members.Count; i++)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
134 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
135 var member = members[i];
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
136
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
137 if (member.Info1 == null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
138 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
139 member.Info1 = new SqlInfo(member.Info2.Members)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
140 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
141 Sql = new SqlValue(null),
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
142 Query = sequence1.SqlQuery,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
143 };
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
144
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
145 member.Member.SequenceInfo = member.Info1;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
146 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
147
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
148 if (member.Info2 == null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
149 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
150 member.Info2 = new SqlInfo(member.Info1.Members)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
151 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
152 Sql = new SqlValue(null),
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
153 Query = sequence2.SqlQuery,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
154 };
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
155 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
156
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
157 sequence1.SqlQuery.Select.Columns.Add(new SqlQuery.Column(sequence1.SqlQuery, member.Info1.Sql));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
158 sequence2.SqlQuery.Select.Columns.Add(new SqlQuery.Column(sequence2.SqlQuery, member.Info2.Sql));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
159
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
160 member.Member.SequenceInfo.Index = i;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
161
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
162 _members[member.Member.MemberExpression.Member] = member.Member;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
163 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
164
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
165 foreach (var key in sequence1.ColumnIndexes.Keys.ToList())
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
166 sequence1.ColumnIndexes[key] = sequence1.SqlQuery.Select.Add(key);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
167
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
168 foreach (var key in sequence2.ColumnIndexes.Keys.ToList())
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
169 sequence2.ColumnIndexes[key] = sequence2.SqlQuery.Select.Add(key);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
170 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
171
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
172 public override void BuildQuery<T>(Query<T> query, ParameterExpression queryParameter)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
173 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
174 var expr = BuildExpression(null, 0);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
175 var mapper = Builder.BuildMapper<T>(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
176
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
177 query.SetQuery(mapper.Compile());
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
178 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
179
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
180 public override Expression BuildExpression(Expression expression, int level)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
181 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
182 if (_isObject)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
183 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
184 if (expression == null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
185 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
186 var type = _methodCall.Method.GetGenericArguments()[0];
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
187 var nctor = (NewExpression)Expression.Find(e =>
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
188 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
189 if (e.NodeType == ExpressionType.New && e.Type == type)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
190 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
191 var ne = (NewExpression)e;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
192 return ne.Arguments != null && ne.Arguments.Count > 0;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
193 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
194
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
195 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
196 });
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
197
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
198 Expression expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
199
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
200 if (nctor != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
201 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
202 var members = nctor.Members
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
203 .Select(m => m is MethodInfo ? TypeHelper.GetPropertyByMethod((MethodInfo)m) : m)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
204 .ToList();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
205
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
206 expr = Expression.New(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
207 nctor.Constructor,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
208 members
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
209 .Select(m => Expression.PropertyOrField(_unionParameter, m.Name))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
210 .Cast<Expression>(),
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
211 members);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
212 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
213 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
214 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
215 var ta = TypeAccessor.GetAccessor(type);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
216
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
217 expr = Expression.MemberInit(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
218 Expression.New(ta.Type),
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
219 _members
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
220 .Select(m => Expression.Bind(m.Value.MemberExpression.Member, m.Value.MemberExpression))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
221 .Cast<MemberBinding>());
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
222 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
223
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
224 var ex = Builder.BuildExpression(this, expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
225
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
226 return ex;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
227 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
228
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
229 if (level == 0 || level == 1)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
230 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
231 var levelExpression = expression.GetLevelExpression(1);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
232
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
233 if (expression == levelExpression && !IsExpression(expression, 1, RequestFor.Object).Result)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
234 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
235 var idx = ConvertToIndex(expression, level, ConvertFlags.Field);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
236 var n = idx[0].Index;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
237
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
238 if (Parent != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
239 n = Parent.ConvertToParentIndex(n, this);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
240
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
241 return Builder.BuildSql(expression.Type, n);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
242 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
243 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
244 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
245
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
246 return base.BuildExpression(expression, level);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
247 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
248
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
249 public override IsExpressionResult IsExpression(Expression expression, int level, RequestFor testFlag)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
250 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
251 if (testFlag == RequestFor.Root && expression == _unionParameter)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
252 return IsExpressionResult.True;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
253
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
254 return base.IsExpression(expression, level, testFlag);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
255 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
256
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
257 public override SqlInfo[] ConvertToIndex(Expression expression, int level, ConvertFlags flags)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
258 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
259 if (_isObject)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
260 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
261 return ConvertToSql(expression, level, flags)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
262 .Select(idx =>
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
263 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
264 if (idx.Index < 0)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
265 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
266 if (idx.Index == -2)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
267 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
268 SqlQuery.Select.Columns.Add(new SqlQuery.Column(SqlQuery, idx.Sql));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
269 idx.Index = SqlQuery.Select.Columns.Count - 1;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
270 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
271 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
272 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
273 idx.Index = SqlQuery.Select.Add(idx.Sql);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
274 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
275 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
276
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
277 return idx;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
278 })
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
279 .ToArray();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
280 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
281
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
282 return base.ConvertToIndex(expression, level, flags);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
283 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
284
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
285 public override SqlInfo[] ConvertToSql(Expression expression, int level, ConvertFlags flags)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
286 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
287 if (_isObject)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
288 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
289 switch (flags)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
290 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
291 case ConvertFlags.All :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
292 case ConvertFlags.Key :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
293
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
294 if (expression == null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
295 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
296 return _members.Values
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
297 .Select(m => ConvertToSql(m.MemberExpression, 0, ConvertFlags.Field)[0])
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
298 .ToArray();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
299 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
300
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
301 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
302
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
303 case ConvertFlags.Field :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
304
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
305 if (expression != null && (level == 0 || level == 1) && expression.NodeType == ExpressionType.MemberAccess)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
306 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
307 var levelExpression = expression.GetLevelExpression(1);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
308
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
309 if (expression == levelExpression)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
310 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
311 var ma = (MemberExpression)expression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
312 var member = _members[ma.Member];
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
313
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
314 if (member.SqlQueryInfo == null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
315 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
316 member.SqlQueryInfo = new SqlInfo(member.MemberExpression.Member)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
317 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
318 Index = -2,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
319 Sql = SubQuery.SqlQuery.Select.Columns[member.SequenceInfo.Index],
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
320 Query = SqlQuery,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
321 };
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
322 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
323
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
324 return new[] { member.SqlQueryInfo };
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
325 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
326 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
327
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
328 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
329 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
330
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
331 throw new InvalidOperationException();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
332 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
333
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
334 return base.ConvertToSql(expression, level, flags);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
335 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
336 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
337
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
338 #endregion
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
339 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
340 }