private DmlfUpdate CompileUpdateCore(Func<TargetColumnSqlModelBase, bool> compareColumn, Func<TargetColumnSqlModelBase, bool> updateColumn, Action<DmlfUpdate> createUpdateSpecialColumns, CompareColumnContext compareContext, UpdateColumnContext updateContext)
        {
            var cmd = new DmlfUpdate();
            cmd.UpdateTarget = new DmlfSource { Alias = "target" };
            cmd.From.Add(SourceJoinModel.SourceToRefsJoin);
            cmd.From.Add(new DmlfFromItem
            {
                Source = new DmlfSource
                {
                    Alias = "target",
                    TableOrView = TargetTableSqlName,
                    LinkedInfo = TargetLinkedInfo,
                }
            });
            CreateKeyCondition(cmd, "target");
            CreateLifetimeConditions(cmd, "target");
            CreateFilterConditions(cmd);

            createUpdateSpecialColumns(cmd);

            foreach (var column in TargetColumns)
            {
                bool? update = _dbsh.LifetimeHandler.UpdateColumn(column.Name, updateContext);
                if (update == null) update = updateColumn(column);
                if (!update.Value) continue;
                cmd.Columns.Add(new DmlfUpdateField
                {
                    TargetColumn = column.Name,
                    Expr = column.CreateSourceExpression(SourceJoinModel, false),
                });
            }

            var orCondition = new DmlfOrCondition();
            foreach (var column in TargetColumns)
            {
                bool? compare = _dbsh.LifetimeHandler.CompareColumn(column.Name, compareContext);

                if (compare == null) compare = compareColumn(column);
                if (!compare.Value) continue;
                if (column.CannotBeCompared) continue;

                orCondition.Conditions.Add(new DmlfNotEqualWithNullTestCondition
                {
                    LeftExpr = column.CreateCompareExpression(column.CreateSourceExpression(SourceJoinModel, false)),
                    RightExpr = column.CreateCompareExpression(column.CreateTargetExpression("target")),
                    CollateSpec = column.UseCollate(SourceJoinModel) ? "DATABASE_DEFAULT" : null,
                });
            }
            if (orCondition.Conditions.Any()) cmd.AddAndCondition(orCondition);

            if (!cmd.Columns.Any()) return null;
            return cmd;
        }
 private DmlfUpdate CompileMarkDeleted()
 {
     var res = new DmlfUpdate();
     res.UpdateTarget = new DmlfSource { Alias = "target" };
     res.SingleFrom.Source = new DmlfSource
     {
         Alias = "target",
         TableOrView = TargetTableSqlName,
         LinkedInfo = TargetLinkedInfo,
     };
     var existSelect = new DmlfSelect();
     res.AddAndCondition(new DmlfNotExistCondition
     {
         Select = existSelect,
     });
     existSelect.SelectAll = true;
     existSelect.From.Add(SourceJoinModel.SourceToRefsJoin);
     CreateKeyCondition(existSelect, "target");
     CreateRestrictionCondition(res, "target");
     CreateLifetimeConditions(res, "target");
     CreateFilterConditions(existSelect);
     _dbsh.LifetimeHandler.CreateSetDeletedUpdateFields(res, "target", this);
     return res;
 }