// new CollectionWrapper<ElementType> { Instance = source.Select((ElementType element) => new Wrapper { }) } private Expression ProjectCollection(Expression source, Type elementType, SelectExpandClause selectExpandClause, IEdmEntityType entityType, IEdmEntitySet entitySet, ExpandedNavigationSelectItem expandedItem) { ParameterExpression element = Expression.Parameter(elementType); // expression // new Wrapper { } Expression projection = ProjectElement(element, selectExpandClause, entityType, entitySet); // expression // (ElementType element) => new Wrapper { } LambdaExpression selector = Expression.Lambda(projection, element); if (expandedItem != null) { source = AddOrderByQueryForSource(source, expandedItem.OrderByOption, elementType); } if (_settings.PageSize.HasValue || (expandedItem != null && (expandedItem.TopOption.HasValue || expandedItem.SkipOption.HasValue))) { // nested paging. Need to apply order by first, and take one more than page size as we need to know // whether the collection was truncated or not while generating next page links. IEnumerable <IEdmStructuralProperty> properties = entityType.Key().Any() ? entityType.Key() : entityType .StructuralProperties() .Where(property => property.Type.IsPrimitive() && !property.Type.IsStream()) .OrderBy(property => property.Name); if (expandedItem == null || expandedItem.OrderByOption == null) { bool alreadyOrdered = false; foreach (var prop in properties) { source = ExpressionHelpers.OrderByPropertyExpression(source, prop.Name, elementType, alreadyOrdered); if (!alreadyOrdered) { alreadyOrdered = true; } } } if (expandedItem != null && expandedItem.SkipOption.HasValue) { Contract.Assert(expandedItem.SkipOption.Value <= Int32.MaxValue); source = ExpressionHelpers.Skip(source, (int)expandedItem.SkipOption.Value, elementType, _settings.EnableConstantParameterization); } if (expandedItem != null && expandedItem.TopOption.HasValue) { Contract.Assert(expandedItem.TopOption.Value <= Int32.MaxValue); source = ExpressionHelpers.Take(source, (int)expandedItem.TopOption.Value, elementType, _settings.EnableConstantParameterization); } source = ExpressionHelpers.Take(source, _settings.PageSize.Value + 1, elementType, _settings.EnableConstantParameterization); } // expression // source.Select((ElementType element) => new Wrapper { }) Expression selectedExpresion = Expression.Call(GetSelectMethod(elementType, projection.Type), source, selector); if (!source.Type.IsCollection()) { if (_settings.HandleNullPropagation == HandleNullPropagationOption.True) { // source == null ? null : projectedCollection return(Expression.Condition( test: Expression.Equal(source, Expression.Constant(null)), ifTrue: Expression.Constant(null, selectedExpresion.Type), ifFalse: selectedExpresion)); } else { return(selectedExpresion); } } else { return(selectedExpresion); } }