public UnionContext(SubQueryContext sequence1, SubQueryContext sequence2, MethodCallExpression methodCall) : base(sequence1) { _sequence1 = sequence1; _sequence2 = sequence2; _methodCall = methodCall; _sequence2.Parent = this; _isObject = sequence1.IsExpression(null, 0, RequestFor.Object).Result || sequence2.IsExpression(null, 0, RequestFor.Object).Result; if (_isObject) { _type = _methodCall.Method.GetGenericArguments()[0]; _unionParameter = Expression.Parameter(_type, "t"); } Init(); }
void Init() { 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]) }; 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.CompareLastMember(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.SelectQuery.Select.Columns.Clear(); _sequence2.SelectQuery.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.SelectQuery, }; member.Member.SequenceInfo = member.Info1; } if (member.Info2 == null) { member.Info2 = new SqlInfo(member.Info1.Members) { Sql = new SqlValue(null), Query = _sequence2.SelectQuery, }; } _sequence1.SelectQuery.Select.Columns.Add(new SelectQuery.Column(_sequence1.SelectQuery, member.Info1.Sql)); _sequence2.SelectQuery.Select.Columns.Add(new SelectQuery.Column(_sequence2.SelectQuery, member.Info2.Sql)); member.Member.SequenceInfo.Index = i; _members[member.Member.MemberExpression.Member] = member.Member; } foreach (var key in _sequence1.ColumnIndexes.Keys.ToList()) { _sequence1.ColumnIndexes[key] = _sequence1.SelectQuery.Select.Add(key); } foreach (var key in _sequence2.ColumnIndexes.Keys.ToList()) { _sequence2.ColumnIndexes[key] = _sequence2.SelectQuery.Select.Add(key); } }