public override Expression BuildExpression(Expression expression, int level, bool enforceServerSide) { if (_isObject) { if (expression == null) { var type = _methodCall.Method.GetGenericArguments()[0]; var nctor = (NewExpression)Expression.Find(e => e is NewExpression ne && e.Type == type && ne.Arguments?.Count > 0); Expression expr; if (nctor != null) { var members = nctor.Members .Select(m => m is MethodInfo ? ((MethodInfo)m).GetPropertyInfo() : m) .ToList(); expr = Expression.New( nctor.Constructor, members.Select(m => Expression.PropertyOrField(_unionParameter, m.Name)), members); } else { var ta = TypeAccessor.GetAccessor(type); expr = Expression.MemberInit( Expression.New(ta.Type), _members.Select(m => Expression.Bind(m.Value.MemberExpression.Member, m.Value.MemberExpression))); } var ex = Builder.BuildExpression(this, expr, enforceServerSide); return(ex); } if (level == 0 || level == 1) { var levelExpression = expression.GetLevelExpression(Builder.MappingSchema, 1); if (ReferenceEquals(expression, levelExpression) && !IsExpression(expression, 1, RequestFor.Object).Result) { var idx = ConvertToIndex(expression, level, ConvertFlags.Field); var n = idx[0].Index; if (Parent != null) { n = Parent.ConvertToParentIndex(n, this); } return(Builder.BuildSql(expression.Type, n)); } } } var ret = _sequence1.BuildExpression(expression, level, enforceServerSide); //if (level == 1) // _sequence2.BuildExpression(expression, level); return(ret); }
public override Expression BuildExpression(Expression expression, int level, bool enforceServerSide) { if (_isObject) { if (expression == null) { var type = _methodCall.Method.GetGenericArguments()[0]; var nctor = (NewExpression)Expression.Find(e => e is NewExpression ne && e.Type == type && ne.Arguments?.Count > 0); Expression expr; if (nctor != null) { var members = nctor.Members .Select(m => m is MethodInfo info ? info.GetPropertyInfo() : m) .ToList(); expr = Expression.New( nctor.Constructor, members.Select(m => Expression.PropertyOrField(_unionParameter, m.Name)), members); var ex = Builder.BuildExpression(this, expr, enforceServerSide); return(ex); } var new1 = Expression.Find(e => e.NodeType == ExpressionType.MemberInit && e.Type == type); var needsRewrite = false; if (new1 != null) { var new2 = _sequence2.Expression.Find(e => e.NodeType == ExpressionType.MemberInit && e.Type == type); if (new2 == null) { needsRewrite = true; } else { // Comparing bindings var init1 = (MemberInitExpression)new1; var init2 = (MemberInitExpression)new2; needsRewrite = init1.Bindings.Count != init2.Bindings.Count; if (!needsRewrite) { var accessorDic = new Dictionary <Expression, QueryableAccessor>(); foreach (var binding in init1.Bindings) { if (binding.BindingType != MemberBindingType.Assignment) { needsRewrite = true; break; } var foundBinding = init2.Bindings.FirstOrDefault(b => b.Member == binding.Member); if (foundBinding == null || foundBinding.BindingType != MemberBindingType.Assignment) { needsRewrite = true; break; } var assignment1 = (MemberAssignment)binding; var assignment2 = (MemberAssignment)foundBinding; if (!assignment1.Expression.EqualsTo(assignment2.Expression, accessorDic, null) || !(assignment1.Expression.NodeType == ExpressionType.MemberAccess || assignment1.Expression.NodeType == ExpressionType.Parameter)) { needsRewrite = true; break; } } } } } if (needsRewrite) { var ta = TypeAccessor.GetAccessor(type); expr = Expression.MemberInit( Expression.New(ta.Type), _members.Select(m => Expression.Bind(m.Value.MemberExpression.Member, m.Value.MemberExpression))); var ex = Builder.BuildExpression(this, expr, enforceServerSide); return(ex); } else { var ex = _sequence1.BuildExpression(null, level, enforceServerSide); return(ex); } } if (level == 0 || level == 1) { var levelExpression = expression.GetLevelExpression(Builder.MappingSchema, 1); if (ReferenceEquals(expression, levelExpression) && !IsExpression(expression, 1, RequestFor.Object).Result) { var idx = ConvertToIndex(expression, level, ConvertFlags.Field); var n = idx[0].Index; if (Parent != null) { n = Parent.ConvertToParentIndex(n, this); } return(Builder.BuildSql(expression.Type, n)); } } } var ret = _sequence1.BuildExpression(expression, level, enforceServerSide); //if (level == 1) // _sequence2.BuildExpression(expression, level); return(ret); }