/// <summary> /// Initializes a new instance of the <see cref="NestedEnumerableExpression"/> class. /// </summary> /// <param name="baseEnumerable">The base enumerable.</param> /// <param name="getNestedEnumerable"> /// Expression that takes elements from the base enumerable and returns nested enumerables. /// </param> /// <param name="elementType">The type of the element of the enumerable.</param> public NestedEnumerableExpression( LinearEnumerableExpression baseEnumerable, Func <ParameterExpression, EnumerableExpression> getNestedEnumerable, Type elementType) { this.BaseEnumerable = baseEnumerable ?? throw new ArgumentNullException(nameof(baseEnumerable)); this.GetNestedEnumerable = getNestedEnumerable ?? throw new ArgumentNullException(nameof(getNestedEnumerable)); this.ElementType = elementType ?? throw new ArgumentNullException(nameof(elementType)); }
/// <summary> /// Takes a selector and uses it to map the elements of an enumerable. /// expression : Expression{IQueryable{T}}. /// selector : ((Expression{U} -> Expression{void}) -> (Expression{T} -> Expression{void})). /// returns : Expression{IQueryable{U}}. /// /// The selector takes a continuation that handles new elements and returns a continuation /// that takes old elements, gets the new element, and passes it into that continuation. /// </summary> /// <param name="expression">The enumerable expression to map.</param> /// <param name="selector">The mapping function.</param> /// <param name="newElementType">The new type of the enumerable.</param> /// <returns>The new mapped enumerable.</returns> private static EnumerableExpression SelectRaw( this EnumerableExpression expression, Func <Func <ParameterExpression, Expression>, Func <ParameterExpression, Expression> > selector, Type newElementType) { return(expression switch { LinearEnumerableExpression linear => new LinearEnumerableExpression( linear.Initialize, linear.HasNext, c => linear.MoveNext(selector(c)), newElementType), NestedEnumerableExpression nested => new NestedEnumerableExpression( nested.BaseEnumerable, e => nested.GetNestedEnumerable(e).SelectRaw(selector, newElementType), newElementType), _ => throw new ArgumentException("Must be a linear or nested enumerable.", nameof(expression)), });