protected override SequenceConvertInfo Convert( ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo, ParameterExpression param) { return(null); }
protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) { return(methodCall.IsQueryable(MethodNames)); }
protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) { var isGroup = methodCall.Method.Name == "GroupJoin"; var outerContext = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0], buildInfo.SelectQuery)); var innerContext = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[1], new SelectQuery())); var context = new SubQueryContext(outerContext); innerContext = isGroup ? new GroupJoinSubQueryContext(innerContext) : new SubQueryContext(innerContext); var join = isGroup ? innerContext.SelectQuery.WeakLeftJoin() : innerContext.SelectQuery.InnerJoin(); var sql = context.SelectQuery; sql.From.Tables[0].Joins.Add(join.JoinedTable); var selector = (LambdaExpression)methodCall.Arguments[4].Unwrap(); context.SetAlias(selector.Parameters[0].Name); innerContext.SetAlias(selector.Parameters[1].Name); var outerKeyLambda = ((LambdaExpression)methodCall.Arguments[2].Unwrap()); var innerKeyLambda = ((LambdaExpression)methodCall.Arguments[3].Unwrap()); var outerKeySelector = outerKeyLambda.Body.Unwrap(); var innerKeySelector = innerKeyLambda.Body.Unwrap(); var outerParent = context.Parent; var innerParent = innerContext.Parent; var outerKeyContext = new ExpressionContext(buildInfo.Parent, context, outerKeyLambda); var innerKeyContext = new InnerKeyContext(buildInfo.Parent, innerContext, innerKeyLambda); // Make join and where for the counter. // if (outerKeySelector.NodeType == ExpressionType.New) { var new1 = (NewExpression)outerKeySelector; var new2 = (NewExpression)innerKeySelector; for (var i = 0; i < new1.Arguments.Count; i++) { var arg1 = new1.Arguments[i]; var arg2 = new2.Arguments[i]; BuildJoin(builder, join, outerKeyContext, arg1, innerKeyContext, arg2); } } else if (outerKeySelector.NodeType == ExpressionType.MemberInit) { var mi1 = (MemberInitExpression)outerKeySelector; var mi2 = (MemberInitExpression)innerKeySelector; for (var i = 0; i < mi1.Bindings.Count; i++) { if (mi1.Bindings[i].Member != mi2.Bindings[i].Member) { throw new LinqException("List of member inits does not match for entity type '{0}'.".Args(outerKeySelector.Type)); } var arg1 = ((MemberAssignment)mi1.Bindings[i]).Expression; var arg2 = ((MemberAssignment)mi2.Bindings[i]).Expression; BuildJoin(builder, join, outerKeyContext, arg1, innerKeyContext, arg2); } } else { BuildJoin(builder, join, outerKeyContext, outerKeySelector, innerKeyContext, innerKeySelector); } builder.ReplaceParent(outerKeyContext, outerParent); builder.ReplaceParent(innerKeyContext, innerParent); if (isGroup) { var inner = (GroupJoinSubQueryContext)innerContext; inner.Join = join.JoinedTable; inner.GetSubQueryContext = () => GetSubQueryContext(builder, methodCall, buildInfo, sql, innerKeyLambda, outerKeySelector, innerKeySelector, outerKeyContext); return(new GroupJoinContext( buildInfo.Parent, selector, context, inner, methodCall.Arguments[1], outerKeyLambda, innerKeyLambda)); } return(new JoinContext(buildInfo.Parent, selector, context, innerContext) #if DEBUG { MethodCall = methodCall } #endif ); }
protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) { return(methodCall.Arguments.Count == 2 && methodCall.IsQueryable("Concat", "Union")); }
IBuildContext GetSubQueryContext(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo, SelectQuery sql, LambdaExpression innerKeyLambda, Expression outerKeySelector, Expression innerKeySelector, IBuildContext outerKeyContext) { var subQueryContext = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[1], new SelectQuery())); subQueryContext = new SubQueryContext(subQueryContext); var subQueryParent = subQueryContext.Parent; var subQueryKeyContext = new ExpressionContext(buildInfo.Parent, subQueryContext, innerKeyLambda); // Process SubQuery. // var subQuerySql = ((SubQueryContext)subQueryContext).SelectQuery; // Make join and where for the counter. // if (outerKeySelector.NodeType == ExpressionType.New) { var new1 = (NewExpression)outerKeySelector; var new2 = (NewExpression)innerKeySelector; for (var i = 0; i < new1.Arguments.Count; i++) { var arg1 = new1.Arguments[i]; var arg2 = new2.Arguments[i]; BuildSubQueryJoin(builder, outerKeyContext, arg1, arg2, subQueryKeyContext, subQuerySql); } } else if (outerKeySelector.NodeType == ExpressionType.MemberInit) { var mi1 = (MemberInitExpression)outerKeySelector; var mi2 = (MemberInitExpression)innerKeySelector; for (var i = 0; i < mi1.Bindings.Count; i++) { if (mi1.Bindings[i].Member != mi2.Bindings[i].Member) { throw new LinqException("List of member inits does not match for entity type '{0}'.".Args(outerKeySelector.Type)); } var arg1 = ((MemberAssignment)mi1.Bindings[i]).Expression; var arg2 = ((MemberAssignment)mi2.Bindings[i]).Expression; BuildSubQueryJoin(builder, outerKeyContext, arg1, arg2, subQueryKeyContext, subQuerySql); } } else { BuildSubQueryJoin(builder, outerKeyContext, outerKeySelector, innerKeySelector, subQueryKeyContext, subQuerySql); } builder.ReplaceParent(subQueryKeyContext, subQueryParent); subQuerySql.ParentSelect = sql; subQuerySql.Select.Columns.Clear(); return(subQueryContext); }