var query =
from o in QueryFactory.CreateLinqQuery<Order>()
where o.OrderNumber == 1
from oi in o.OrderItems.Take (o.OrderNumber + 1)
select oi;
CheckQueryResult (query, DomainObjectIDs.OrderItem1, DomainObjectIDs.OrderItem2);
Change Take.Count to be an Expression.
Change Take.ExecuteInMemory to throw a NotSupportedException if Count is not a ConstantExpression. (We cannot support executing dependent subqueries in memory without knowing what the outer object values are.)
To resolve,
Change ResultType property to GetResultType method.
To calculate the result type, start from the select clause, construct IQueryable<SelectorType>, then iterate over result operators, call "GetModifiedResultType (oldResultType)". Return result.
Requirements:
(Note: We assume that result type is always IQueryable<T> or a scalar value. This might change in the future if a feature request asks us to support "custom" queryable types.)
Add IQuerySource interface:
Change QuerySourceReferenceExpression.ReferencedClause to be IQuerySourceClause
Change ClauseMapping to use IQuerySourceClause instead of IClause
Change Backend to throw an exception when ReferencedClause is no FromClauseBase (for now)
Check ItemName, ItemType, references, etc.
Create GroupJoinClause
See JoinExpressionNode (COMMONS-1343)
Similar to JoinClause, but additional InnerItemType, InnerItemName properties
ItemType is of type IEnumerable<?>, InnerItemType should be extracted via ParserUtility.GetEnumerableItemType in the constructor
Implement GroupJoinExpressionNode : MethodCallExpressionNodeBase
Inner, OuterKeySelector, InnerKeySelector, ResultSelector
Parsing + Tests
Create a JoinClause
Check ItemName, ItemType, references, etc.
Implement IBodyClause
Remove FromClauseBase.JoinClause property
Adapt visitors
Clone method must add join clause to mapping (see FromClauseBase)
GetResolved... => Source.Resolve (...)
GetResolvedResultSelector => replace IEnumerable<TInner> parameter with QuerySourceReferenceExpression to this clause
Resolve => replace parameterToBeResolved with GetResolvedResultSelector()