protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) { // UpdateWhenMatchedAndThenDelete(merge, searchCondition, setter, deleteCondition) var mergeContext = (MergeContext)builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); var statement = mergeContext.Merge; var operation = new SqlMergeOperationClause(MergeOperationType.UpdateWithDelete); statement.Operations.Add(operation); var predicate = methodCall.Arguments[1]; var setter = methodCall.Arguments[2]; var deletePredicate = methodCall.Arguments[3]; if (!(setter is ConstantExpression constSetter) || constSetter.Value != null) { var setterExpression = (LambdaExpression)setter.Unwrap(); UpdateBuilder.BuildSetterWithContext( builder, buildInfo, setterExpression, mergeContext.TargetContext, operation.Items, mergeContext.TargetContext, mergeContext.SourceContext); }
private void BuildMergeOperation(SqlMergeOperationClause operation) { switch (operation.OperationType) { case MergeOperationType.Update: BuildMergeOperationUpdate(operation); break; case MergeOperationType.Delete: BuildMergeOperationDelete(operation); break; case MergeOperationType.Insert: BuildMergeOperationInsert(operation); break; case MergeOperationType.UpdateWithDelete: BuildMergeOperationUpdateWithDelete(operation); break; case MergeOperationType.DeleteBySource: BuildMergeOperationDeleteBySource(operation); break; case MergeOperationType.UpdateBySource: BuildMergeOperationUpdateBySource(operation); break; default: throw new InvalidOperationException($"Unknown merge operation type: {operation.OperationType}"); } }
protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) { var mergeContext = (MergeContext)builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); var statement = mergeContext.Merge; var operation = new SqlMergeOperationClause(MergeOperationType.Insert); statement.Operations.Add(operation); var predicate = methodCall.Arguments[1]; var setter = methodCall.Arguments[2]; if (!(setter is ConstantExpression constSetter) || constSetter.Value != null) { var setterExpression = (LambdaExpression)setter.Unwrap(); mergeContext.AddSourceParameter(setterExpression.Parameters[0]); UpdateBuilder.BuildSetterWithContext( builder, buildInfo, setterExpression, mergeContext.TargetContext, operation.Items, mergeContext.SourceContext); }
protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) { // UpdateWhenNotMatchedBySourceAnd(merge, searchCondition, setter) var mergeContext = (MergeContext)builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); var statement = mergeContext.Merge; var operation = new SqlMergeOperationClause(MergeOperationType.UpdateBySource); statement.Operations.Add(operation); Expression predicate = methodCall.Arguments[1]; Expression setter = methodCall.Arguments[2]; UpdateBuilder.BuildSetter( builder, buildInfo, (LambdaExpression)setter.Unwrap(), mergeContext, operation.Items, mergeContext); if (!predicate.IsNullValue()) { var condition = (LambdaExpression)predicate.Unwrap(); operation.Where = BuildSearchCondition(builder, statement, mergeContext.TargetContext, null, condition); } return(mergeContext); }
protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) { var mergeContext = (MergeContext)builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); var statement = mergeContext.Merge; var operation = new SqlMergeOperationClause(MergeOperationType.DeleteBySource); statement.Operations.Add(operation); var predicate = methodCall.Arguments[1]; if (!(predicate is ConstantExpression constPredicate) || constPredicate.Value != null) { var condition = (LambdaExpression)predicate.Unwrap(); var conditionExpr = builder.ConvertExpression(condition.Body.Unwrap()); operation.Where = new SqlSearchCondition(); builder.BuildSearchCondition( new ExpressionContext(null, new[] { mergeContext.TargetContext }, condition), conditionExpr, operation.Where.Conditions, false); } return(mergeContext); }
protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) { // UpdateWhenMatchedAndThenDelete(merge, searchCondition, setter, deleteCondition) var mergeContext = (MergeContext)builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); var statement = mergeContext.Merge; var operation = new SqlMergeOperationClause(MergeOperationType.UpdateWithDelete); statement.Operations.Add(operation); var predicate = methodCall.Arguments[1]; var setter = methodCall.Arguments[2]; var deletePredicate = methodCall.Arguments[3]; if (!setter.IsNullValue()) { var setterExpression = (LambdaExpression)setter.Unwrap(); UpdateBuilder.BuildSetterWithContext( builder, buildInfo, setterExpression, mergeContext.TargetContext, operation.Items, mergeContext.TargetContext, mergeContext.SourceContext); } else { // build setters like QueryRunner.Update var sqlTable = (SqlTable)statement.Target.Source; var param = Expression.Parameter(sqlTable.ObjectType, "s"); var keys = sqlTable.GetKeys(false).Cast <SqlField>().ToList(); foreach (var field in sqlTable.Fields.Where(f => f.IsUpdatable).Except(keys)) { var expression = LinqToDB.Expressions.Extensions.GetMemberGetter(field.ColumnDescriptor.MemberInfo, param); var tgtExpr = mergeContext.TargetContext.ConvertToSql(builder.ConvertExpression(expression), 1, ConvertFlags.Field)[0].Sql; var srcExpr = mergeContext.SourceContext.ConvertToSql(builder.ConvertExpression(expression), 1, ConvertFlags.Field)[0].Sql; operation.Items.Add(new SqlSetExpression(tgtExpr, srcExpr)); } } if (!predicate.IsNullValue()) { var predicateCondition = (LambdaExpression)predicate.Unwrap(); operation.Where = BuildSearchCondition(builder, statement, mergeContext.TargetContext, mergeContext.SourceContext, predicateCondition); } if (!deletePredicate.IsNullValue()) { var deleteCondition = (LambdaExpression)deletePredicate.Unwrap(); operation.WhereDelete = BuildSearchCondition(builder, statement, mergeContext.TargetContext, mergeContext.SourceContext, deleteCondition);; } return(mergeContext); }
protected override void BuildMergeOperationUpdateWithDelete(SqlMergeOperationClause operation) { BuildMergeOperationUpdate(operation); StringBuilder .AppendLine() .AppendLine("DELETE WHERE") .Append("\t"); BuildSearchCondition(Precedence.Unknown, operation.WhereDelete !); }
protected virtual void BuildMergeOperationDelete(SqlMergeOperationClause operation) { StringBuilder .Append("WHEN MATCHED"); if (operation.Where != null) { StringBuilder.Append(" AND "); BuildSearchCondition(Precedence.Unknown, operation.Where, wrapCondition: true); } StringBuilder.AppendLine(" THEN DELETE"); }
protected override void BuildMergeOperationDeleteBySource(SqlMergeOperationClause operation) { StringBuilder .Append("WHEN NOT MATCHED BY SOURCE"); if (operation.Where != null) { StringBuilder.Append(" AND "); BuildSearchCondition(Precedence.Unknown, operation.Where, wrapCondition: true); } StringBuilder.AppendLine(" THEN DELETE"); }
protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) { var mergeContext = (MergeContext)builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); var statement = mergeContext.Merge; var operation = new SqlMergeOperationClause(MergeOperationType.DeleteBySource); statement.Operations.Add(operation); var predicate = methodCall.Arguments[1]; if (!predicate.IsNullValue()) { var condition = (LambdaExpression)predicate.Unwrap(); operation.Where = BuildSearchCondition(builder, statement, mergeContext.TargetContext, null, condition); } return(mergeContext); }
protected override void BuildMergeOperationUpdateBySource(SqlMergeOperationClause operation) { StringBuilder .AppendLine() .Append("WHEN NOT MATCHED By Source"); if (operation.Where != null) { StringBuilder.Append(" AND "); BuildSearchCondition(Precedence.Unknown, operation.Where, wrapCondition: true); } StringBuilder.AppendLine(" THEN UPDATE"); var update = new SqlUpdateClause(); update.Items.AddRange(operation.Items); BuildUpdateSet(null, update); }
protected override void BuildMergeOperationInsert(SqlMergeOperationClause operation) { StringBuilder .AppendLine() .AppendLine("WHEN NOT MATCHED THEN") .Append("INSERT"); var insertClause = new SqlInsertClause(); insertClause.Items.AddRange(operation.Items); BuildInsertClause(new SqlInsertOrUpdateStatement(null), insertClause, null, false, false); if (operation.Where != null) { StringBuilder.Append(" WHERE "); BuildSearchCondition(Precedence.Unknown, operation.Where); } }
protected virtual void BuildMergeOperationUpdate(SqlMergeOperationClause operation) { StringBuilder .AppendLine() .Append("WHEN MATCHED"); if (operation.Where != null) { StringBuilder.Append(" AND "); BuildSearchCondition(Precedence.Unknown, operation.Where); } StringBuilder.AppendLine(" THEN"); StringBuilder.AppendLine("UPDATE"); var update = new SqlUpdateClause(); update.Items.AddRange(operation.Items); BuildUpdateSet(null, update); }
protected virtual void BuildMergeOperationUpdateBySource(SqlMergeOperationClause operation) { // SQL Server-specific operation throw new NotSupportedException($"Merge operation {operation.OperationType} is not supported by {Name}"); }
protected virtual void BuildMergeOperationUpdateWithDelete(SqlMergeOperationClause operation) { // Oracle-specific operation throw new NotSupportedException($"Merge operation {operation.OperationType} is not supported by {Name}"); }
protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) { var mergeContext = (MergeContext)builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); var statement = mergeContext.Merge; var operation = new SqlMergeOperationClause(MergeOperationType.Insert); statement.Operations.Add(operation); var predicate = methodCall.Arguments[1]; var setter = methodCall.Arguments[2]; if (!setter.IsNullValue()) { var setterExpression = (LambdaExpression)setter.Unwrap(); mergeContext.AddSourceParameter(setterExpression.Parameters[0]); UpdateBuilder.BuildSetterWithContext( builder, buildInfo, setterExpression, mergeContext.TargetContext, operation.Items, mergeContext.SourceContext); } else { // build setters like QueryRunner.Insert var sqlTable = (SqlTable)statement.Target.Source; var param = Expression.Parameter(sqlTable.ObjectType, "s"); foreach (var field in sqlTable.Fields) { if (field.IsInsertable) { var expression = LinqToDB.Expressions.Extensions.GetMemberGetter(field.ColumnDescriptor.MemberInfo, param); var tgtExpr = mergeContext.TargetContext.ConvertToSql(builder.ConvertExpression(expression), 1, ConvertFlags.Field)[0].Sql; var srcExpr = mergeContext.SourceContext.ConvertToSql(builder.ConvertExpression(expression), 1, ConvertFlags.Field)[0].Sql; operation.Items.Add(new SqlSetExpression(tgtExpr, srcExpr)); } else if (field.IsIdentity) { var expr = builder.DataContext.CreateSqlProvider().GetIdentityExpression(sqlTable); if (expr != null) { operation.Items.Add(new SqlSetExpression(field, expr)); } } } } if (!predicate.IsNullValue()) { var condition = (LambdaExpression)predicate.Unwrap(); var conditionExpr = builder.ConvertExpression(condition.Body.Unwrap()); operation.Where = new SqlSearchCondition(); builder.BuildSearchCondition( new ExpressionContext(null, new[] { mergeContext.SourceContext }, condition), conditionExpr, operation.Where.Conditions); } return(mergeContext); }