protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) { // MergeInto<TTarget, TSource>(IQueryable<TSource> source, ITable<TTarget> target, string hint) var sourceContext = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0], new SelectQuery())); var target = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[1]) { AssociationsAsSubQueries = true }); if (target is not TableBuilder.TableContext tableContext || !tableContext.SelectQuery.IsSimple) { throw new NotImplementedException("Currently, only CTEs are supported as the target of a merge. You can fix by calling .AsCte() on the parameter before passing into .MergeInto()."); } var targetTable = tableContext.SqlTable; var merge = new SqlMergeStatement(targetTable); if (methodCall.Arguments.Count == 3) { merge.Hint = (string?)methodCall.Arguments[2].EvaluateExpression(); } target.SetAlias(merge.Target.Alias !); target.Statement = merge; var source = new TableLikeQueryContext(sourceContext); return(new MergeContext(merge, target, source)); }
protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) { var mergeContext = (MergeContext)builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); if (LinqExtensions.UsingMethodInfo1 == methodCall.Method.GetGenericMethodDefinition()) { var sourceContext = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[1], new SelectQuery())); var source = new TableLikeQueryContext(sourceContext); mergeContext.Sequences = new IBuildContext[] { mergeContext.Sequence, source }; mergeContext.Merge.Source = source.Source; } else { var enumerableBuildInfo = new BuildInfo(buildInfo, methodCall.Arguments[1], new SelectQuery()); var type = FindType(builder, enumerableBuildInfo); var sourceContext = new EnumerableContext(builder, enumerableBuildInfo, enumerableBuildInfo.SelectQuery, type, builder.ConvertToSql(buildInfo.Parent, enumerableBuildInfo.Expression)); var source = new TableLikeQueryContext(sourceContext); mergeContext.Sequences = new IBuildContext[] { mergeContext.Sequence, source }; mergeContext.Merge.Source = source.Source; } return(mergeContext); }
protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) { var mergeContext = (MergeContext)builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); var sourceContext = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[1], new SelectQuery())); var source = new TableLikeQueryContext(sourceContext); mergeContext.Sequences = new IBuildContext[] { mergeContext.Sequence, source }; mergeContext.Merge.Source = source.Source; return(mergeContext); }
protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) { var mergeContext = (MergeContext)builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); // is it ok to reuse context like that? var source = new TableLikeQueryContext(mergeContext.TargetContext); mergeContext.Sequences = new IBuildContext[] { mergeContext.Sequence, source }; mergeContext.Merge.Source = source.Source; return(mergeContext); }
protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) { // MergeInto<TTarget, TSource>(IQueryable<TSource> source, ITable<TTarget> target, string hint) var sourceContext = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0], new SelectQuery())); var target = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[1]) { AssociationsAsSubQueries = true }); var targetTable = ((TableBuilder.TableContext)target).SqlTable; var merge = new SqlMergeStatement(targetTable) { Hint = (string?)methodCall.Arguments[2].EvaluateExpression() }; target.SetAlias(merge.Target.Alias !); target.Statement = merge; var source = new TableLikeQueryContext(sourceContext); return(new MergeContext(merge, target, source)); }
public MergeContext(SqlMergeStatement merge, IBuildContext target, TableLikeQueryContext source) : base(null, new[] { target, source }, null) { Statement = merge; merge.Source = source.Source; }