/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public override void VisitGroupJoinClause(GroupJoinClause groupJoinClause, QueryModel queryModel, int index) { base.VisitGroupJoinClause(groupJoinClause, queryModel, index); // Attempts to rewrite GroupJoin/SelectMany to regular join var additionalFromClause = queryModel.BodyClauses.ElementAtOrDefault(index + 1) as AdditionalFromClause; if (additionalFromClause?.FromExpression is QuerySourceReferenceExpression querySourceReferenceExpression && querySourceReferenceExpression.ReferencedQuerySource == groupJoinClause) { if (queryModel.CountQuerySourceReferences(groupJoinClause) == 1) { // GroupJoin/SelectMany can be rewritten to regular Join. queryModel.BodyClauses.RemoveAt(index + 1); queryModel.BodyClauses.RemoveAt(index); queryModel.BodyClauses.Insert(index, groupJoinClause.JoinClause); UpdateQuerySourceMapping( queryModel, additionalFromClause, new QuerySourceReferenceExpression(groupJoinClause.JoinClause)); } } }
public new void ToString() { var joinClause = new JoinClause("x", typeof(Cook), Expression.Constant(0), Expression.Constant(1), Expression.Constant(2)); var groupJoinClause = new GroupJoinClause("y", typeof(IEnumerable <Cook>), joinClause); Assert.That(groupJoinClause.ToString(), Is.EqualTo("join Cook x in 0 on 1 equals 2 into IEnumerable`1 y")); }
public virtual void VisitGroupJoinClause(GroupJoinClause groupJoinClause, QueryModel queryModel, int index) { ArgumentUtility.CheckNotNull("groupJoinClause", groupJoinClause); ArgumentUtility.CheckNotNull("queryModel", queryModel); groupJoinClause.JoinClause.Accept(this, queryModel, groupJoinClause); }
public override void VisitGroupJoinClause(GroupJoinClause groupJoinClause, QueryModel queryModel, int index) { JoinClause joinClause = (JoinClause)groupJoinClause.JoinClause; Type tOuter = queryModel.MainFromClause.ItemType; Type tInner = joinClause.ItemType; Type tOuterKey = joinClause.OuterKeySelector.Type; Type tInnerKey = joinClause.InnerKeySelector.Type; Type tIEnumerableInner = typeof(IEnumerable <>).MakeGenericType(tInner); Type tResult = queryModel.SelectClause.Selector.Type; ParameterExpression iEnumerableInnerParameter = Expression.Parameter(tIEnumerableInner, "d"); ParameterExpression outerParameter = Expression.Parameter(tOuter, "p"); ParameterExpression innerParameter = Expression.Parameter(tInner, "d"); ParameterExpression outerKeyParameter = Expression.Parameter(tOuter, "p"); Expression outerKey = UpdateExpressionVisitor.Update(joinClause.OuterKeySelector, new[] { outerKeyParameter }, dbContext, queryContext); LambdaExpression outerKeyLamda = Expression.Lambda(outerKey, outerKeyParameter); ParameterExpression tInnerKeyParameter = Expression.Parameter(tInner, "d"); Expression innerKey = UpdateExpressionVisitor.Update(joinClause.InnerKeySelector, new[] { tInnerKeyParameter }, dbContext, queryContext); LambdaExpression innerKeyLamda = Expression.Lambda(innerKey, tInnerKeyParameter); Expression selector = UpdateExpressionVisitor.Update(queryModel.SelectClause.Selector, new[] { outerParameter, iEnumerableInnerParameter }, dbContext, queryContext); LambdaExpression selectorLambda = Expression.Lambda(selector, new[] { outerParameter, iEnumerableInnerParameter }); MethodInfo groupJoin = GetMethods("GroupJoin", expression.Type, 4).Where(p => p.GetParameters().Count() == 5).Single(). MakeGenericMethod(new Type[] { tOuter, tInner, tOuterKey, tResult }); expression = Expression.Call(groupJoin, new[] { expression, joinClause.InnerSequence, outerKeyLamda, innerKeyLamda, selectorLambda }); flagsNotVisitSelector = true; }
private void ProcessFlattenedJoin(GroupJoinClause nonAggregatingJoin, QuerySourceUsageLocator locator) { var nhJoin = locator.LeftJoin ? new NhOuterJoinClause(nonAggregatingJoin.JoinClause) : (IQuerySource)nonAggregatingJoin.JoinClause; // Need to: // 1. Remove the group join and replace it with a join // 2. Remove the corresponding "from" clause (the thing that was doing the flattening) // 3. Rewrite the query model to reference the "join" rather than the "from" clause SwapClause(nonAggregatingJoin, (IBodyClause)nhJoin); _model.BodyClauses.Remove((IBodyClause)locator.Usages[0]); SwapQuerySourceVisitor querySourceSwapper; if (locator.LeftJoin) { // As we wrapped the join clause we have to update all references to the wrapped clause querySourceSwapper = new SwapQuerySourceVisitor(nonAggregatingJoin.JoinClause, nhJoin); _model.TransformExpressions(querySourceSwapper.Swap); } querySourceSwapper = new SwapQuerySourceVisitor(locator.Usages[0], nhJoin); _model.TransformExpressions(querySourceSwapper.Swap); }
public override void VisitGroupJoinClause(GroupJoinClause groupJoinClause, QueryModel queryModel, int index) { _queryParts.AddOuterJoinPart( GetPsqlExpression(groupJoinClause.JoinClause.OuterKeySelector), GetPsqlExpression(groupJoinClause.JoinClause.InnerKeySelector)); base.VisitGroupJoinClause(groupJoinClause, queryModel, index); }
public void Intialize() { var groupJoinClause = new GroupJoinClause("x", typeof(IEnumerable <Cook>), _joinClause); Assert.That(groupJoinClause.ItemName, Is.SameAs("x")); Assert.That(groupJoinClause.ItemType, Is.SameAs(typeof(IEnumerable <Cook>))); Assert.That(groupJoinClause.JoinClause, Is.SameAs(_joinClause)); }
protected virtual Expression CompileGroupJoinInnerSequenceExpression( [NotNull] GroupJoinClause groupJoinClause, [NotNull] QueryModel queryModel) { Check.NotNull(groupJoinClause, nameof(groupJoinClause)); Check.NotNull(queryModel, nameof(queryModel)); return(ReplaceClauseReferences(groupJoinClause.JoinClause.InnerSequence, groupJoinClause.JoinClause)); }
protected override Expression VisitQuerySourceReferenceExpression(QuerySourceReferenceExpression expression) { if (_results.AggregatingClauses.Contains(expression.ReferencedQuerySource as GroupJoinClause)) { _groupJoin = expression.ReferencedQuerySource as GroupJoinClause; } return(base.VisitQuerySourceReferenceExpression(expression)); }
public virtual void VisitJoinClause(JoinClause joinClause, QueryModel queryModel, GroupJoinClause groupJoinClause) { ArgumentUtility.CheckNotNull("joinClause", joinClause); ArgumentUtility.CheckNotNull("queryModel", queryModel); ArgumentUtility.CheckNotNull("groupJoinClause", groupJoinClause); // nothing to do here }
protected override Expression CompileGroupJoinInnerSequenceExpression(GroupJoinClause groupJoinClause, QueryModel queryModel) { Check.NotNull(groupJoinClause, nameof(groupJoinClause)); Check.NotNull(queryModel, nameof(queryModel)); var expression = base.CompileGroupJoinInnerSequenceExpression(groupJoinClause, queryModel); return(LiftSubQuery(groupJoinClause.JoinClause, groupJoinClause.JoinClause.InnerSequence, queryModel, expression)); }
protected override Expression VisitQuerySourceReferenceExpression(QuerySourceReferenceExpression expression) { if (_results.AggregatingClauses.Contains(expression.ReferencedQuerySource as GroupJoinClause)) { _groupJoin = expression.ReferencedQuerySource as GroupJoinClause; } return base.VisitQuerySourceReferenceExpression(expression); }
public override void VisitGroupJoinClause(GroupJoinClause groupJoinClause, QueryModel queryModel, int index) { if (!IsLeftJoin(groupJoinClause, queryModel, index)) { MarkForMaterialization(queryModel.MainFromClause); MarkForMaterialization(groupJoinClause); } base.VisitGroupJoinClause(groupJoinClause, queryModel, index); }
public override void VisitGroupJoinClause( [NotNull] GroupJoinClause groupJoinClause, [NotNull] QueryModel queryModel, int index) { Check.NotNull(groupJoinClause, "groupJoinClause"); Check.NotNull(queryModel, "queryModel"); var innerSequenceExpression = ReplaceClauseReferences( CreateQueryingExpressionTreeVisitor(groupJoinClause.JoinClause) .VisitExpression(groupJoinClause.JoinClause.InnerSequence)); var innerElementType = innerSequenceExpression.Type.GetSequenceType(); var itemParameter = Expression.Parameter(innerElementType); _querySourceMapping.AddMapping(groupJoinClause.JoinClause, itemParameter); var outerKeySelector = ReplaceClauseReferences( CreateQueryingExpressionTreeVisitor(groupJoinClause) .VisitExpression(groupJoinClause.JoinClause.OuterKeySelector)); var innerKeySelector = ReplaceClauseReferences( CreateQueryingExpressionTreeVisitor(groupJoinClause) .VisitExpression(groupJoinClause.JoinClause.InnerKeySelector)); var itemsParameter = Expression.Parameter(innerSequenceExpression.Type); var scopeCreatorExpression = QuerySourceScope .Create(groupJoinClause, itemsParameter, _querySourceScopeParameter); _expression = Expression.Call( _queryCompilationContext.LinqOperatorProvider.GroupJoin.MakeGenericMethod( typeof(QuerySourceScope), innerElementType, outerKeySelector.Type, typeof(QuerySourceScope)), _expression, innerSequenceExpression, Expression.Lambda(outerKeySelector, _querySourceScopeParameter), Expression.Lambda(innerKeySelector, itemParameter), Expression.Lambda( scopeCreatorExpression, new[] { _querySourceScopeParameter, itemsParameter })); _querySourceMapping.AddMapping( groupJoinClause, QuerySourceScope.GetResult(_querySourceScopeParameter, groupJoinClause, innerSequenceExpression.Type)); }
protected override Expression VisitQuerySourceReference(QuerySourceReferenceExpression expression) { var groupJoinClause = expression.ReferencedQuerySource as GroupJoinClause; if (groupJoinClause != null && _results.AggregatingClauses.Contains(groupJoinClause)) { _groupJoin = groupJoinClause; } return(base.VisitQuerySourceReference(expression)); }
public override void VisitGroupJoinClause( [NotNull] GroupJoinClause groupJoinClause, [NotNull] QueryModel queryModel, int index) { Check.NotNull(groupJoinClause, nameof(groupJoinClause)); Check.NotNull(queryModel, nameof(queryModel)); var outerKeySelectorExpression = ReplaceClauseReferences(groupJoinClause.JoinClause.OuterKeySelector, groupJoinClause); var innerSequenceExpression = CompileGroupJoinInnerSequenceExpression(groupJoinClause, queryModel); var innerItemParameter = Expression.Parameter( innerSequenceExpression.Type.GetSequenceType(), groupJoinClause.JoinClause.ItemName); _queryCompilationContext.QuerySourceMapping .AddMapping(groupJoinClause.JoinClause, innerItemParameter); var innerKeySelectorExpression = ReplaceClauseReferences(groupJoinClause.JoinClause.InnerKeySelector, groupJoinClause); var innerItemsParameter = Expression.Parameter( LinqOperatorProvider.MakeSequenceType(innerItemParameter.Type), groupJoinClause.ItemName); var transparentIdentifierType = typeof(TransparentIdentifier <,>) .MakeGenericType(CurrentParameter.Type, innerItemsParameter.Type); _expression = Expression.Call( LinqOperatorProvider.GroupJoin .MakeGenericMethod( CurrentParameter.Type, innerItemParameter.Type, outerKeySelectorExpression.Type, transparentIdentifierType), _expression, innerSequenceExpression, Expression.Lambda(outerKeySelectorExpression, CurrentParameter), Expression.Lambda(innerKeySelectorExpression, innerItemParameter), Expression.Lambda( CallCreateTransparentIdentifier( transparentIdentifierType, CurrentParameter, innerItemsParameter), CurrentParameter, innerItemsParameter)); IntroduceTransparentScope(groupJoinClause, queryModel, index, transparentIdentifierType); }
public override void SetUp() { base.SetUp(); _innerSequence = ExpressionHelper.CreateExpression(); _outerKeySelector = ExpressionHelper.CreateLambdaExpression <string, string> (o => o.ToString()); _innerKeySelector = ExpressionHelper.CreateLambdaExpression <string, string> (i => i.ToString()); _resultSelector = ExpressionHelper.CreateLambdaExpression <string, IEnumerable <string>, string> ((o, into) => o.ToString() + into.ToString()); _node = new GroupJoinExpressionNode( CreateParseInfo(SourceNode, "groupJoin"), _innerSequence, _outerKeySelector, _innerKeySelector, _resultSelector); _groupJoinClause = ExpressionHelper.CreateGroupJoinClause <Cook>(); }
public override void VisitGroupJoinClause(GroupJoinClause groupJoinClause, QueryModel queryModel, int index) { Check.NotNull(groupJoinClause, nameof(groupJoinClause)); Check.NotNull(queryModel, nameof(queryModel)); OptimizeJoinClause( groupJoinClause.JoinClause, queryModel, index, () => base.VisitGroupJoinClause(groupJoinClause, queryModel, index), LinqOperatorProvider.GroupJoin, outerJoin: true); }
private bool IsFlattenedJoin(GroupJoinClause nonAggregatingJoin) { if (_locator.Clauses.Count == 1) { var from = _locator.Clauses[0] as AdditionalFromClause; if (from != null) { return(true); } } return(false); }
protected override void ApplyNodeSpecificSemantics(QueryModel queryModel, ClauseGenerationContext clauseGenerationContext) { ArgumentUtility.CheckNotNull("queryModel", queryModel); var joinClause = _joinExpressionNode.CreateJoinClause(clauseGenerationContext); var groupJoinClause = new GroupJoinClause(_resultSelector.Parameters[1].Name, _resultSelector.Parameters[1].Type, joinClause); clauseGenerationContext.AddContextInfo(this, groupJoinClause); queryModel.BodyClauses.Add(groupJoinClause); var selectClause = queryModel.SelectClause; selectClause.Selector = GetResolvedResultSelector(clauseGenerationContext); }
protected override QueryModel ApplyNodeSpecificSemantics(QueryModel queryModel, ClauseGenerationContext clauseGenerationContext) { var joinClause = JoinExpressionNode.CreateJoinClause(clauseGenerationContext); var groupJoinClause = new GroupJoinClause(ResultSelector.Parameters[1].Name, ResultSelector.Parameters[1].Type, joinClause); clauseGenerationContext.AddContextInfo(this, groupJoinClause); queryModel.BodyClauses.Add(groupJoinClause); var selectClause = queryModel.SelectClause; selectClause.Selector = GetResolvedResultSelector(clauseGenerationContext); return(queryModel); }
private bool IsFlattenedJoin(GroupJoinClause nonAggregatingJoin, QuerySourceUsageLocator locator) { if (locator.Usages.Count == 1) { var from = locator.Usages[0] as AdditionalFromClause; if (from != null) { return(true); } } return(false); }
public override void VisitJoinClause(JoinClause joinClause, QueryModel queryModel, GroupJoinClause groupJoinClause) { // Store the group join with the expectation it will be used later by an additional from clause EnsureNotArraySubquery(); _unclaimedGroupJoins.Add(new UnclaimedGroupJoin() { JoinClause = joinClause, GroupJoinClause = groupJoinClause }); base.VisitJoinClause(joinClause, queryModel, groupJoinClause); }
private void ProcessFlattenedJoin(GroupJoinClause nonAggregatingJoin) { // Need to: // 1. Remove the group join and replace it with a join // 2. Remove the corresponding "from" clause (the thing that was doing the flattening) // 3. Rewrite the selector to reference the "join" rather than the "from" clause SwapClause(nonAggregatingJoin, nonAggregatingJoin.JoinClause); // TODO - don't like use of _locator here; would rather we got this passed in. Ditto on next line (esp. the cast) _model.BodyClauses.Remove(_locator.Clauses[0]); var querySourceSwapper = new SwapQuerySourceVisitor((IQuerySource)_locator.Clauses[0], nonAggregatingJoin.JoinClause); _model.SelectClause.TransformExpressions(querySourceSwapper.Swap); }
public override void VisitGroupJoinClause(GroupJoinClause groupJoinClause, QueryModel queryModel, int index) { var itemParameter = Expression.Parameter(groupJoinClause.JoinClause.ItemType); _querySourceMapping.AddMapping(groupJoinClause.JoinClause, itemParameter); var innerSequence = ReplaceClauseReferences( CreateQueryingExpressionTreeVisitor(null) .VisitExpression(groupJoinClause.JoinClause.InnerSequence)); var outerKeySelector = ReplaceClauseReferences( CreateQueryingExpressionTreeVisitor(this) .VisitExpression(groupJoinClause.JoinClause.OuterKeySelector)); var innerKeySelector = ReplaceClauseReferences( CreateQueryingExpressionTreeVisitor(this) .VisitExpression(groupJoinClause.JoinClause.InnerKeySelector)); var itemsParameter = Expression.Parameter(groupJoinClause.ItemType); var scopeCreatorExpression = QuerySourceScope .Create(groupJoinClause, itemsParameter, _querySourceScopeParameter); _expression = Expression.Call( _linqOperatorProvider.GroupJoin.MakeGenericMethod( typeof(QuerySourceScope), groupJoinClause.JoinClause.ItemType, outerKeySelector.Type, typeof(QuerySourceScope)), _expression, innerSequence, Expression.Lambda(outerKeySelector, _querySourceScopeParameter), Expression.Lambda(innerKeySelector, itemParameter), Expression.Lambda( scopeCreatorExpression, new[] { _querySourceScopeParameter, itemsParameter })); _querySourceMapping.AddMapping( groupJoinClause, QuerySourceScope.GetResult(_querySourceScopeParameter, groupJoinClause)); }
public void VisitQuerySourceReferenceExpression_WithOrderings_AndDoNotExtractOrdingsPolicy() { var sqlTable = SqlStatementModelObjectMother.CreateSqlTable(typeof(Cook)); var sqlTableReferenceExpression = new SqlTableReferenceExpression(sqlTable); var selectProjection = new NamedExpression("test", Expression.MakeMemberAccess(sqlTableReferenceExpression, typeof(Cook).GetProperty("Name"))); var orderingExpression = Expression.MakeMemberAccess(sqlTableReferenceExpression, typeof(Cook).GetProperty("ID")); var sqlStatement = new SqlStatementBuilder { DataInfo = new StreamedSequenceInfo(typeof(DateTime[]), Expression.Constant(new DateTime(2000, 1, 1))), SelectProjection = selectProjection, SqlTables = { sqlTable }, Orderings = { new Ordering(orderingExpression, OrderingDirection.Asc) } }.GetSqlStatement(); var fakeWhereExpression = Expression.Constant(true); var innerSequenceExpression = new SqlSubStatementExpression(sqlStatement); var joinClause = new JoinClause( "x", typeof(Cook[]), innerSequenceExpression, Expression.Constant(new Cook()), Expression.Constant(new Cook())); var groupJoinClause = new GroupJoinClause("g", typeof(Cook[]), joinClause); var querySourceReferenceExpression = new QuerySourceReferenceExpression(groupJoinClause); _stageMock .Expect(mock => mock.PrepareWhereExpression(Arg <Expression> .Matches(e => e is BinaryExpression), Arg.Is(_context))) .WhenCalled( mi => SqlExpressionTreeComparer.CheckAreEqualTrees( Expression.Equal(groupJoinClause.JoinClause.OuterKeySelector, groupJoinClause.JoinClause.InnerKeySelector), (Expression)mi.Arguments[0])) .Return(fakeWhereExpression); _stageMock.Replay(); var visitor = CreateTestableVisitor(OrderingExtractionPolicy.DoNotExtractOrderings); visitor.VisitQuerySourceReference(querySourceReferenceExpression); _stageMock.VerifyAllExpectations(); Assert.That(visitor.FromExpressionInfo != null); // inline condition because of ReSharper var fromExpressionInfo = (FromExpressionInfo)visitor.FromExpressionInfo; Assert.That(fromExpressionInfo.ExtractedOrderings, Is.Empty); }
public void VisitQuerySourceReferenceExpression_WithNonNullWhereCondition() { var memberInfo = typeof(Cook).GetProperty("Assistants"); var sqlTableReferenceExpression = new SqlTableReferenceExpression(SqlStatementModelObjectMother.CreateSqlTable(typeof(Cook))); var innerSequenceExpression = Expression.MakeMemberAccess( sqlTableReferenceExpression, memberInfo); var joinClause = new JoinClause( "x", typeof(Cook[]), innerSequenceExpression, Expression.Constant(new Cook()), Expression.Constant(new Cook())); var groupJoinClause = new GroupJoinClause("g", typeof(Cook[]), joinClause); var querySourceReferenceExpression = new QuerySourceReferenceExpression(groupJoinClause); var fakeWhereExpression = Expression.Constant(true); _stageMock .Expect(mock => mock.PrepareWhereExpression(Arg <Expression> .Matches(e => e is BinaryExpression), Arg.Is(_context))) .WhenCalled( mi => SqlExpressionTreeComparer.CheckAreEqualTrees( Expression.Equal(groupJoinClause.JoinClause.OuterKeySelector, groupJoinClause.JoinClause.InnerKeySelector), (Expression)mi.Arguments[0])) .Return(fakeWhereExpression); _stageMock.Replay(); var visitor = CreateTestableVisitor(_someOrderingExtractionPolicy); visitor.VisitQuerySourceReference(querySourceReferenceExpression); _stageMock.VerifyAllExpectations(); Assert.That(visitor.FromExpressionInfo != null); // inline condition because of ReSharper var fromExpressionInfo = (FromExpressionInfo)visitor.FromExpressionInfo; Assert.That(fromExpressionInfo.WhereCondition, Is.AssignableTo(typeof(BinaryExpression))); Assert.That(fromExpressionInfo.WhereCondition.NodeType, Is.EqualTo(ExpressionType.AndAlso)); Assert.That(((BinaryExpression)fromExpressionInfo.WhereCondition).Left, Is.TypeOf(typeof(JoinConditionExpression))); Assert.That(((JoinConditionExpression)((BinaryExpression)fromExpressionInfo.WhereCondition).Left).JoinedTable.JoinInfo, Is.TypeOf(typeof(UnresolvedCollectionJoinInfo))); Assert.That( ((UnresolvedCollectionJoinInfo)((JoinConditionExpression)((BinaryExpression)fromExpressionInfo.WhereCondition).Left).JoinedTable.JoinInfo).SourceExpression, Is.SameAs(sqlTableReferenceExpression)); Assert.That( ((UnresolvedCollectionJoinInfo)((JoinConditionExpression)((BinaryExpression)fromExpressionInfo.WhereCondition).Left).JoinedTable.JoinInfo).MemberInfo, Is.SameAs(memberInfo)); Assert.That(((JoinConditionExpression)((BinaryExpression)fromExpressionInfo.WhereCondition).Left).JoinedTable.JoinSemantics, Is.EqualTo(JoinSemantics.Inner)); Assert.That(((BinaryExpression)fromExpressionInfo.WhereCondition).Right, Is.SameAs(fakeWhereExpression)); }
public override void VisitGroupJoinClause(GroupJoinClause groupJoinClause, QueryModel queryModel, int index) { AppendLine(); base.VisitGroupJoinClause(groupJoinClause, queryModel, index); TransformingVisitor.StringBuilder.Append($" into {groupJoinClause.ItemName}"); if (TransformingVisitor.GenerateUniqueQsreIds) { var i = TransformingVisitor.VisitedQuerySources.IndexOf(groupJoinClause); if (i == -1) { i = TransformingVisitor.VisitedQuerySources.Count; TransformingVisitor.VisitedQuerySources.Add(groupJoinClause); } TransformingVisitor.StringBuilder.Append($"{{{i}}}"); } }
public void SetUp() { _mockRepository = new MockRepository(); _visitorMock = _mockRepository.StrictMock <TestQueryModelVisitor>(); _bodyClauseMock1 = _mockRepository.StrictMock <IBodyClause>(); _bodyClauseMock2 = _mockRepository.StrictMock <IBodyClause>(); _ordering1 = new Ordering(ExpressionHelper.CreateExpression(), OrderingDirection.Asc); _ordering2 = new Ordering(ExpressionHelper.CreateExpression(), OrderingDirection.Asc); _resultOperator1 = new TestResultOperator(); _resultOperator2 = new TestResultOperator(); _queryModel = ExpressionHelper.CreateQueryModel <Cook>(); _orderByClause = ExpressionHelper.CreateOrderByClause(); _groupJoinClause = ExpressionHelper.CreateGroupJoinClause <Cook>(); }
protected override Expression VisitSubQuery(SubQueryExpression expression) { // If the sub query's main (and only) from clause is one of our aggregating group bys, then swap it GroupJoinClause groupJoin = LocateGroupJoinQuerySource(expression.QueryModel); if (groupJoin != null) { Expression innerSelector = new SwapQuerySourceVisitor(groupJoin.JoinClause, expression.QueryModel.MainFromClause). Swap(groupJoin.JoinClause.InnerKeySelector); expression.QueryModel.MainFromClause.FromExpression = groupJoin.JoinClause.InnerSequence; // TODO - this only works if the key selectors are not composite. Needs improvement... expression.QueryModel.BodyClauses.Add(new WhereClause(Expression.Equal(innerSelector, groupJoin.JoinClause.OuterKeySelector))); } return(expression); }
protected override void ApplyNodeSpecificSemantics(QueryModel queryModel, ClauseGenerationContext clauseGenerationContext) { ArgumentUtility.CheckNotNull("queryModel", queryModel); var joinResultSelector = Expression.Lambda(Expression.Constant(null), _outerKeySelector.Parameters[0], _innerKeySelector.Parameters[0]); var joinParseInfo = new MethodCallExpressionParseInfo(AssociatedIdentifier, Source, _parsedExpression); var joinExpressionNode = new JoinExpressionNode(joinParseInfo, _innerSequence, _outerKeySelector, _innerKeySelector, joinResultSelector); var joinClause = joinExpressionNode.CreateJoinClause(clauseGenerationContext); var groupJoinClause = new GroupJoinClause(_resultSelector.Parameters[1].Name, _resultSelector.Parameters[1].Type, joinClause); clauseGenerationContext.AddContextInfo(this, groupJoinClause); queryModel.BodyClauses.Add(groupJoinClause); var selectClause = queryModel.SelectClause; selectClause.Selector = GetResolvedResultSelector(clauseGenerationContext); }
public override void VisitGroupJoinClause(GroupJoinClause groupJoinClause, QueryModel queryModel, int index) { throw new NotSupportedException( "Adding a join ... into ... implementation to the query provider is left to the reader for extra points."); }
public override void VisitGroupJoinClause(GroupJoinClause groupJoinClause, QueryModel queryModel, int index) { throw new NotSupportedException("LinqToExcel does not provide support for group join"); }
private void ProcessFlattenedJoin(GroupJoinClause nonAggregatingJoin) { // Need to: // 1. Remove the group join and replace it with a join // 2. Remove the corresponding "from" clause (the thing that was doing the flattening) // 3. Rewrite the selector to reference the "join" rather than the "from" clause SwapClause(nonAggregatingJoin, nonAggregatingJoin.JoinClause); // TODO - don't like use of _locator here; would rather we got this passed in. Ditto on next line (esp. the cast) _model.BodyClauses.Remove(_locator.Clauses[0]); var querySourceSwapper = new SwapQuerySourceVisitor((IQuerySource) _locator.Clauses[0], nonAggregatingJoin.JoinClause); _model.SelectClause.TransformExpressions(querySourceSwapper.Swap); }
private bool IsHierarchicalJoin(GroupJoinClause nonAggregatingJoin) { return _locator.Clauses.Count == 0; }
private bool IsFlattenedJoin(GroupJoinClause nonAggregatingJoin) { if (_locator.Clauses.Count == 1) { var from = _locator.Clauses[0] as AdditionalFromClause; if (from != null) { return true; } } return false; }
private bool IsOuterJoin(GroupJoinClause nonAggregatingJoin) { return false; }