protected override Expression VisitMemberInit(MemberInitExpression node) { ODataExpansionOptions expansion = expansions.First(); if (node.NewExpression.Type != expansion.ParentType) { return(base.VisitMemberInit(node)); } return(Expression.MemberInit ( Expression.New(node.Type), node.Bindings.OfType <MemberAssignment>().Aggregate ( new List <MemberBinding>(), AddBinding ) )); List <MemberBinding> AddBinding(List <MemberBinding> list, MemberAssignment binding) { if (ListTypesAreEquivalent(binding.Member.GetMemberType(), expansion.MemberType) && string.Compare(binding.Member.Name, expansion.MemberName, true) == 0) //found the expansion { if (foundExpansions.Count > 0) { throw new NotSupportedException("Recursive queries not supported"); } AddBindingExpression(GetBindingExpression(binding, expansion)); } else { list.Add(binding); } return(list); void AddBindingExpression(Expression bindingExpression) { list.Add(Expression.Bind(binding.Member, bindingExpression)); foundExpansions.Add(bindingExpression); } } }
protected override Expression GetBindingExpression(MemberAssignment binding, ODataExpansionOptions expansion) { if (expansion.FilterOptions != null) { return(FilterAppender.AppendFilter(binding.Expression, expansion)); } else if (expansions.Count > 1) //Mutually exclusive with expansion.Filter != null. { //There can be only one filter in the list. See the GetFilters() method in QueryableExtensions.UpdateQueryable. return(UpdaterExpansion ( binding.Expression, expansions.Skip(1).ToList() )); } else { throw new ArgumentException("Last expansion in the list must have a filter", nameof(expansions)); } }
protected abstract Expression GetBindingExpression(MemberAssignment binding, ODataExpansionOptions expansion);
public static Expression AppendQueryMethod(Expression expression, ODataExpansionOptions expansion) => new MethodAppender(expression, expansion).Visit(expression);
public MethodAppender(Expression expression, ODataExpansionOptions expansion) { this.expansion = expansion; this.expression = expression; }
public FilterAppender(Expression expression, ODataExpansionOptions expansion) { this.expansion = expansion; this.expression = expression; }
public static Expression AppendFilter(Expression expression, ODataExpansionOptions expansion) => new FilterAppender(expression, expansion).Visit(expression);