public static IEnumerable <(string Name, ServerScriptModelColumn Value)> Columns(
            Context context, SiteSettings ss, BaseItemModel model)
        {
            var mine    = model.Mine(context: context);
            var columns = Def
                          .ColumnDefinitionCollection
                          .Where(definition => definition.TableName == ss?.ReferenceType)
                          .Select(definition =>
            {
                Column column = null;
                ss?.ColumnHash?.TryGetValue(definition.ColumnName, out column);
                return(
                    definition.ColumnName,
                    model.ServerScriptModelRow.Columns?.Get(column?.ColumnName)
                    ?? new ServerScriptModelColumn(
                        labelText: column?.LabelText,
                        labelRaw: string.Empty,
                        rawText: string.Empty,
                        readOnly: column?.EditorReadOnly == true,
                        hide: column?.Hide == true,
                        validateRequired: column?.ValidateRequired == true,
                        extendedFieldCss: column?.ExtendedFieldCss,
                        extendedControlCss: column?.ExtendedControlCss,
                        extendedCellCss: column?.ExtendedCellCss,
                        extendedHtmlBeforeField: column?.ExtendedHtmlBeforeField,
                        extendedHtmlBeforeLabel: column?.ExtendedHtmlBeforeLabel,
                        extendedHtmlBetweenLabelAndControl: column?.ExtendedHtmlBetweenLabelAndControl,
                        extendedHtmlAfterControl: column?.ExtendedHtmlAfterControl,
                        extendedHtmlAfterField: column?.ExtendedHtmlAfterField));
            })
                          .ToArray();

            return(columns);
        }
        private static Column[] FilterCanUpdateColumns(
            Context context,
            SiteSettings ss,
            BaseItemModel model,
            IEnumerable <string> columnNames)
        {
            var mine    = model?.Mine(context: context);
            var columns = columnNames
                          .Distinct()
                          .Select(columnName => ss.ColumnHash.TryGetValue(columnName, out var column)
                    ? column
                    : null)
                          .Where(column => column?.CanEdit(
                                     context: context,
                                     ss: ss,
                                     mine: mine,
                                     skipCanReadCheck: true) == true)
                          .ToArray();

            return(columns);
        }
        private static Dictionary <string, ServerScriptModelColumn> SetColumns(
            Context context,
            SiteSettings ss,
            ExpandoObject columns,
            BaseItemModel model)
        {
            var mine         = model?.Mine(context: context);
            var scriptValues = new Dictionary <string, ServerScriptModelColumn>();

            columns?.ForEach(datam =>
            {
                if (!ss.ColumnHash.TryGetValue(datam.Key, out var column))
                {
                    return;
                }
                var serverScriptColumn = datam.Value as ServerScriptModelColumn;
                if (serverScriptColumn.Changed())
                {
                    scriptValues[datam.Key] = serverScriptColumn;
                }
            });
            return(scriptValues);
        }
        public static IEnumerable <(string Name, object Value)> Values(
            Context context, SiteSettings ss, BaseItemModel model)
        {
            var mine   = model?.Mine(context: context);
            var values = new List <(string, object)>();

            values.Add(ReadNameValue(
                           context: context,
                           ss: ss,
                           columnName: nameof(model.SiteId),
                           value: model.SiteId,
                           mine: mine));
            values.Add(ReadNameValue(
                           context: context,
                           ss: ss,
                           columnName: nameof(model.Title),
                           value: model.Title?.Value,
                           mine: mine));
            values.Add(ReadNameValue(
                           context: context,
                           ss: ss,
                           columnName: nameof(model.Body),
                           value: model.Body,
                           mine: mine));
            values.Add(ReadNameValue(
                           context: context,
                           ss: ss,
                           columnName: nameof(model.Ver),
                           value: model.Ver,
                           mine: mine));
            values.Add(ReadNameValue(
                           context: context,
                           ss: ss,
                           columnName: nameof(model.Creator),
                           value: model.Creator.Id,
                           mine: mine));
            values.Add(ReadNameValue(
                           context: context,
                           ss: ss,
                           columnName: nameof(model.Updator),
                           value: model.Updator.Id,
                           mine: mine));
            values.Add(ReadNameValue(
                           context: context,
                           ss: ss,
                           columnName: nameof(model.CreatedTime),
                           value: model.CreatedTime?.Value,
                           mine: mine));
            values.Add(ReadNameValue(
                           context: context,
                           ss: ss,
                           columnName: nameof(model.UpdatedTime),
                           value: model.UpdatedTime?.Value,
                           mine: mine));
            values.AddRange(model
                            .ClassHash
                            .Select(element => ReadNameValue(
                                        context: context,
                                        ss: ss,
                                        columnName: element.Key,
                                        value: element.Value,
                                        mine: mine)));
            values.AddRange(model
                            .NumHash
                            .Select(element => ReadNameValue(
                                        context: context,
                                        ss: ss,
                                        columnName: element.Key,
                                        value: element.Value.Value
                                        ?? (ss?.GetColumn(
                                                context: context,
                                                columnName: element.Key)
                                            ?.Nullable == true
                                    ? (decimal?)null
                                    : 0),
                                        mine: mine)));
            values.AddRange(model
                            .DateHash
                            .Select(element => ReadNameValue(
                                        context: context,
                                        ss: ss,
                                        columnName: element.Key,
                                        value: element.Value,
                                        mine: mine)));
            values.AddRange(model
                            .DescriptionHash
                            .Select(element => ReadNameValue(
                                        context: context,
                                        ss: ss,
                                        columnName: element.Key,
                                        value: element.Value,
                                        mine: mine)));
            values.AddRange(model
                            .CheckHash
                            .Select(element => ReadNameValue(
                                        context: context,
                                        ss: ss,
                                        columnName: element.Key,
                                        value: element.Value,
                                        mine: mine)));
            if (model is IssueModel issueModel)
            {
                values.Add(ReadNameValue(
                               context: context,
                               ss: ss,
                               columnName: nameof(IssueModel.IssueId),
                               value: issueModel.IssueId,
                               mine: mine));
                values.Add(ReadNameValue(
                               context: context,
                               ss: ss,
                               columnName: nameof(IssueModel.StartTime),
                               value: issueModel.StartTime,
                               mine: mine));
                values.Add(ReadNameValue(
                               context: context,
                               ss: ss,
                               columnName: nameof(IssueModel.CompletionTime),
                               value: issueModel.CompletionTime.Value,
                               mine: mine));
                values.Add(ReadNameValue(
                               context: context,
                               ss: ss,
                               columnName: nameof(IssueModel.WorkValue),
                               value: issueModel.WorkValue.Value,
                               mine: mine));
                values.Add(ReadNameValue(
                               context: context,
                               ss: ss,
                               columnName: nameof(IssueModel.ProgressRate),
                               value: issueModel.ProgressRate.Value,
                               mine: mine));
                values.Add(ReadNameValue(
                               context: context,
                               ss: ss,
                               columnName: nameof(IssueModel.RemainingWorkValue),
                               value: issueModel.RemainingWorkValue.Value,
                               mine: mine));
                values.Add(ReadNameValue(
                               context: context,
                               ss: ss,
                               columnName: nameof(IssueModel.Status),
                               value: issueModel.Status?.Value,
                               mine: mine));
                values.Add(ReadNameValue(
                               context: context,
                               ss: ss,
                               columnName: nameof(IssueModel.Manager),
                               value: issueModel.Manager.Id,
                               mine: mine));
                values.Add(ReadNameValue(
                               context: context,
                               ss: ss,
                               columnName: nameof(IssueModel.Owner),
                               value: issueModel.Owner.Id,
                               mine: mine));
                values.Add(ReadNameValue(
                               context: context,
                               ss: ss,
                               columnName: nameof(IssueModel.Locked),
                               value: issueModel.Locked,
                               mine: mine));
            }
            if (model is ResultModel resultModel)
            {
                values.Add(ReadNameValue(
                               context: context,
                               ss: ss,
                               columnName: nameof(ResultModel.ResultId),
                               value: resultModel.ResultId,
                               mine: mine));
                values.Add(ReadNameValue(
                               context: context,
                               ss: ss,
                               columnName: nameof(ResultModel.Status),
                               value: resultModel.Status?.Value,
                               mine: mine));
                values.Add(ReadNameValue(
                               context: context,
                               ss: ss,
                               columnName: nameof(ResultModel.Manager),
                               value: resultModel.Manager.Id,
                               mine: mine));
                values.Add(ReadNameValue(
                               context: context,
                               ss: ss,
                               columnName: nameof(ResultModel.Owner),
                               value: resultModel.Owner.Id,
                               mine: mine));
                values.Add(ReadNameValue(
                               context: context,
                               ss: ss,
                               columnName: nameof(ResultModel.Locked),
                               value: resultModel.Locked,
                               mine: mine));
            }
            return(values.ToArray());
        }