public UnionContext(SubQueryContext sequence1, SubQueryContext sequence2, MethodCallExpression methodCall) : base(sequence1) { _methodCall = methodCall; _isObject = sequence1.IsExpression(null, 0, RequestFor.Object).Result || sequence2.IsExpression(null, 0, RequestFor.Object).Result; if (_isObject) { var type = _methodCall.Method.GetGenericArguments()[0]; _unionParameter = Expression.Parameter(type, "t"); } Init(sequence1, sequence2); }
void Init(SubQueryContext sequence1, SubQueryContext sequence2) { var info1 = sequence1.ConvertToIndex(null, 0, ConvertFlags.All).ToList(); var info2 = sequence2.ConvertToIndex(null, 0, ConvertFlags.All).ToList(); if (!_isObject) { return; } var members = new List <UnionMember>(); foreach (var info in info1) { if (info.Members.Count == 0) { throw new InvalidOperationException(); } var member = new Member { SequenceInfo = info, MemberExpression = Expression.MakeMemberAccess(_unionParameter, info.Members[0]) }; //if (sequence1.IsExpression(member.MemberExpression, 1, RequestFor.Object).Result) // throw new LinqException("Types in {0} are constructed incompatibly.", _methodCall.Method.Name); members.Add(new UnionMember { Member = member, Info1 = info }); } foreach (var info in info2) { if (info.Members.Count == 0) { throw new InvalidOperationException(); } var em = members.FirstOrDefault(m => m.Member.SequenceInfo != null && m.Member.SequenceInfo.CompareMembers(info)); if (em == null) { var member = new Member { MemberExpression = Expression.MakeMemberAccess(_unionParameter, info.Members[0]) }; if (sequence2.IsExpression(member.MemberExpression, 1, RequestFor.Object).Result) { throw new LinqException("Types in {0} are constructed incompatibly.", _methodCall.Method.Name); } members.Add(new UnionMember { Member = member, Info2 = info }); } else { em.Info2 = info; } } sequence1.SqlQuery.Select.Columns.Clear(); sequence2.SqlQuery.Select.Columns.Clear(); for (var i = 0; i < members.Count; i++) { var member = members[i]; if (member.Info1 == null) { member.Info1 = new SqlInfo(member.Info2.Members) { Sql = new SqlValue(null), Query = sequence1.SqlQuery, }; member.Member.SequenceInfo = member.Info1; } if (member.Info2 == null) { member.Info2 = new SqlInfo(member.Info1.Members) { Sql = new SqlValue(null), Query = sequence2.SqlQuery, }; } sequence1.SqlQuery.Select.Columns.Add(new SqlQuery.Column(sequence1.SqlQuery, member.Info1.Sql)); sequence2.SqlQuery.Select.Columns.Add(new SqlQuery.Column(sequence2.SqlQuery, member.Info2.Sql)); member.Member.SequenceInfo.Index = i; //member.Info1.Index = i; //member.Info2.Index = i; _members[member.Member.MemberExpression.Member] = member.Member; } foreach (var key in sequence1.ColumnIndexes.Keys.ToList()) { sequence1.ColumnIndexes[key] = sequence1.SqlQuery.Select.Add(key); } foreach (var key in sequence2.ColumnIndexes.Keys.ToList()) { sequence2.ColumnIndexes[key] = sequence2.SqlQuery.Select.Add(key); } /* * if (_isObject) * { * foreach (var info in info1) * { * if (info.Member == null) * throw new InvalidOperationException(); * * CheckAndAddMember(sequence1, sequence2, info); * } * * info2 = sequence2.ConvertToIndex(null, 0, ConvertFlags.All).OrderBy(_ => _.Index).ToList(); * * if (info1.Count != info2.Count) * { * for (var i = 0; i < info2.Count; i++) * { * if (i < info1.Count) * { * if (info1[i].Index != info2[i].Index) * throw new InvalidOperationException(); * } * else * { * CheckAndAddMember(sequence2, sequence1, info2[i]); * } * } * } * } * else * sequence2.ConvertToIndex(null, 0, ConvertFlags.All).OrderBy(_ => _.Index).ToList(); */ }