SortProperties() public method

Comma-delimited list of the Entity properties that should be used for Sorting. Normally, you should leave this as null which will make it sort on the returned field To disable sorting for this field, return string.Empty;
public SortProperties ( string selection ) : string
selection string
return string
Exemplo n.º 1
0
        /// <summary>
        /// Binds the grid.
        /// </summary>
        /// <param name="report">The report.</param>
        /// <param name="gReport">The g report.</param>
        /// <param name="currentPerson">The current person.</param>
        /// <param name="dataViewFilterOverrides">The data view filter overrides.</param>
        /// <param name="databaseTimeoutSeconds">The database timeout seconds.</param>
        /// <param name="isCommunication">if set to <c>true</c> [is communication].</param>
        /// <param name="errorMessage">The error message.</param>
        public static void BindGrid(Report report, Grid gReport, Person currentPerson, DataViewFilterOverrides dataViewFilterOverrides, int?databaseTimeoutSeconds, bool isCommunication, out string errorMessage)
        {
            errorMessage = null;
            if (report != null)
            {
                var errors = new List <string>();

                if (!report.EntityTypeId.HasValue)
                {
                    gReport.Visible = false;
                    return;
                }

                var rockContext = new RockContext();

                if (!report.IsAuthorized(Authorization.VIEW, currentPerson))
                {
                    gReport.Visible = false;
                    return;
                }

                Type entityType = EntityTypeCache.Get(report.EntityTypeId.Value, rockContext).GetEntityType();
                if (entityType == null)
                {
                    errorMessage = string.Format("Unable to determine entityType for {0}", report.EntityType);
                    return;
                }

                gReport.EntityTypeId = report.EntityTypeId;

                bool isPersonDataSet = report.EntityTypeId == EntityTypeCache.Get(typeof(Rock.Model.Person), true, rockContext).Id;

                if (isPersonDataSet)
                {
                    gReport.PersonIdField = "Id";
                    gReport.DataKeyNames  = new string[] { "Id" };
                }
                else
                {
                    gReport.PersonIdField = null;
                }

                if (report.EntityTypeId.HasValue)
                {
                    gReport.RowItemText = EntityTypeCache.Get(report.EntityTypeId.Value, rockContext).FriendlyName;
                }

                List <EntityField> entityFields = Rock.Reporting.EntityHelper.GetEntityFields(entityType, true, false);

                var selectedEntityFields = new Dictionary <int, EntityField>();
                var selectedAttributes   = new Dictionary <int, AttributeCache>();
                var selectedComponents   = new Dictionary <int, ReportField>();

                // if there is a selectField, keep it to preserve which items are checked
                var selectField = gReport.Columns.OfType <SelectField>().FirstOrDefault();
                gReport.Columns.Clear();
                int columnIndex = 0;

                if (!string.IsNullOrWhiteSpace(gReport.PersonIdField))
                {
                    // if we already had a selectField, use it (to preserve checkbox state)
                    gReport.Columns.Add(selectField ?? new SelectField());
                    columnIndex++;
                }

                var reportFieldSortExpressions = new Dictionary <Guid, string>();

                gReport.CommunicateMergeFields = new List <string>();
                gReport.CommunicationRecipientPersonIdFields = new List <string>();

                foreach (var reportField in report.ReportFields.OrderBy(a => a.ColumnOrder))
                {
                    bool mergeField     = reportField.IsCommunicationMergeField.HasValue && reportField.IsCommunicationMergeField.Value;
                    bool recipientField = reportField.IsCommunicationRecipientField.HasValue && reportField.IsCommunicationRecipientField.Value;

                    columnIndex++;
                    if (reportField.ReportFieldType == ReportFieldType.Property)
                    {
                        var entityField = entityFields.FirstOrDefault(a => a.Name == reportField.Selection);
                        if (entityField != null)
                        {
                            selectedEntityFields.Add(columnIndex, entityField);

                            BoundField boundField = entityField.GetBoundFieldType();
                            boundField.DataField      = string.Format("Entity_{0}_{1}", entityField.Name, columnIndex);
                            boundField.HeaderText     = string.IsNullOrWhiteSpace(reportField.ColumnHeaderText) ? entityField.Title : reportField.ColumnHeaderText;
                            boundField.SortExpression = boundField.DataField;
                            reportFieldSortExpressions.AddOrReplace(reportField.Guid, boundField.SortExpression);
                            boundField.Visible = reportField.ShowInGrid;
                            gReport.Columns.Add(boundField);

                            if (mergeField)
                            {
                                gReport.CommunicateMergeFields.Add($"{boundField.DataField}|{boundField.HeaderText.RemoveSpecialCharacters()}");
                            }
                            if (recipientField)
                            {
                                gReport.CommunicationRecipientPersonIdFields.Add(boundField.DataField);
                            }
                        }
                    }
                    else if (reportField.ReportFieldType == ReportFieldType.Attribute)
                    {
                        Guid?attributeGuid = reportField.Selection.AsGuidOrNull();
                        if (attributeGuid.HasValue)
                        {
                            var attribute = AttributeCache.Get(attributeGuid.Value, rockContext);
                            if (attribute != null && attribute.IsActive)
                            {
                                selectedAttributes.Add(columnIndex, attribute);

                                BoundField boundField;

                                if (attribute.FieldType.Guid.Equals(Rock.SystemGuid.FieldType.BOOLEAN.AsGuid()))
                                {
                                    boundField = new BoolField();
                                }
                                else if (attribute.FieldType.Guid.Equals(Rock.SystemGuid.FieldType.DEFINED_VALUE.AsGuid()))
                                {
                                    boundField = new DefinedValueField();
                                }
                                else
                                {
                                    boundField            = new CallbackField();
                                    boundField.HtmlEncode = false;
                                    (boundField as CallbackField).OnFormatDataValue += (sender, e) => {
                                        string resultHtml = null;
                                        if (e.DataValue != null)
                                        {
                                            bool condensed = true;
                                            resultHtml = attribute.FieldType.Field.FormatValueAsHtml(gReport, e.DataValue.ToString(), attribute.QualifierValues, condensed);
                                        }

                                        e.FormattedValue = resultHtml ?? string.Empty;
                                    };
                                }

                                boundField.DataField      = string.Format("Attribute_{0}_{1}", attribute.Id, columnIndex);
                                boundField.HeaderText     = string.IsNullOrWhiteSpace(reportField.ColumnHeaderText) ? attribute.Name : reportField.ColumnHeaderText;
                                boundField.SortExpression = boundField.DataField;
                                reportFieldSortExpressions.AddOrReplace(reportField.Guid, boundField.SortExpression);

                                if (attribute.FieldType.Guid.Equals(Rock.SystemGuid.FieldType.INTEGER.AsGuid()) ||
                                    attribute.FieldType.Guid.Equals(Rock.SystemGuid.FieldType.DATE.AsGuid()) ||
                                    attribute.FieldType.Guid.Equals(Rock.SystemGuid.FieldType.FILTER_DATE.AsGuid()))
                                {
                                    boundField.HeaderStyle.HorizontalAlign = HorizontalAlign.Right;
                                    boundField.ItemStyle.HorizontalAlign   = HorizontalAlign.Right;
                                }

                                boundField.Visible = reportField.ShowInGrid;

                                gReport.Columns.Add(boundField);

                                if (mergeField)
                                {
                                    gReport.CommunicateMergeFields.Add($"{boundField.DataField}|{boundField.HeaderText.RemoveSpecialCharacters()}");
                                }
                                if (recipientField)
                                {
                                    gReport.CommunicationRecipientPersonIdFields.Add(boundField.DataField);
                                }
                            }
                        }
                    }
                    else if (reportField.ReportFieldType == ReportFieldType.DataSelectComponent)
                    {
                        selectedComponents.Add(columnIndex, reportField);

                        DataSelectComponent selectComponent = DataSelectContainer.GetComponent(reportField.DataSelectComponentEntityType.Name);
                        if (selectComponent != null)
                        {
                            try
                            {
                                DataControlField columnField = selectComponent.GetGridField(entityType, reportField.Selection ?? string.Empty);
                                string           fieldId     = $"{selectComponent.ColumnPropertyName}_{columnIndex}";

                                if (columnField is BoundField)
                                {
                                    (columnField as BoundField).DataField = $"Data_{fieldId}";
                                    var  customSortProperties = selectComponent.SortProperties(reportField.Selection ?? string.Empty);
                                    bool sortReversed         = selectComponent.SortReversed(reportField.Selection ?? string.Empty);
                                    if (customSortProperties != null)
                                    {
                                        if (customSortProperties == string.Empty)
                                        {
                                            // disable sorting if customSortExpression set to string.empty
                                            columnField.SortExpression = string.Empty;
                                        }
                                        else
                                        {
                                            columnField.SortExpression = customSortProperties.Split(',').Select(a => string.Format("Sort_{0}_{1}", a, columnIndex)).ToList().AsDelimited(",");
                                        }
                                    }
                                    else
                                    {
                                        // use default sorting if customSortExpression was null
                                        columnField.SortExpression = (columnField as BoundField).DataField;
                                    }

                                    if (sortReversed == true && !string.IsNullOrWhiteSpace(columnField.SortExpression))
                                    {
                                        columnField.SortExpression = columnField.SortExpression + " DESC";
                                    }
                                }

                                columnField.HeaderText = string.IsNullOrWhiteSpace(reportField.ColumnHeaderText) ? selectComponent.ColumnHeaderText : reportField.ColumnHeaderText;
                                if (!string.IsNullOrEmpty(columnField.SortExpression))
                                {
                                    reportFieldSortExpressions.AddOrReplace(reportField.Guid, columnField.SortExpression);
                                }

                                columnField.Visible = reportField.ShowInGrid;
                                gReport.Columns.Add(columnField);

                                if (mergeField)
                                {
                                    gReport.CommunicateMergeFields.Add($"Data_{fieldId}|{columnField.HeaderText.RemoveSpecialCharacters()}");
                                }
                                if (recipientField)
                                {
                                    string fieldName = (selectComponent is IRecipientDataSelect) ? $"Recipient_{fieldId}" : $"Data_{fieldId}";
                                    gReport.CommunicationRecipientPersonIdFields.Add(fieldName);
                                }
                            }
                            catch (Exception ex)
                            {
                                ExceptionLogService.LogException(ex, HttpContext.Current);
                                errors.Add(string.Format("{0} - {1}", selectComponent, ex.Message));
                            }
                        }
                    }
                }

                // if no fields are specified, show the default fields (Previewable/All) for the EntityType
                var dataColumns = gReport.Columns.OfType <object>().Where(a => a.GetType() != typeof(SelectField));
                if (dataColumns.Count() == 0)
                {
                    // show either the Previewable Columns or all (if there are no previewable columns)
                    bool showAllColumns = !entityFields.Any(a => a.FieldKind == FieldKind.Property && a.IsPreviewable);
                    foreach (var entityField in entityFields.Where(a => a.FieldKind == FieldKind.Property))
                    {
                        columnIndex++;
                        selectedEntityFields.Add(columnIndex, entityField);

                        BoundField boundField = entityField.GetBoundFieldType();

                        boundField.DataField      = string.Format("Entity_{0}_{1}", entityField.Name, columnIndex);
                        boundField.HeaderText     = entityField.Name;
                        boundField.SortExpression = boundField.DataField;
                        boundField.Visible        = showAllColumns || entityField.IsPreviewable;
                        gReport.Columns.Add(boundField);
                    }
                }

                try
                {
                    gReport.Visible        = true;
                    gReport.ExportFilename = report.Name;
                    SortProperty sortProperty = gReport.SortProperty;
                    if (sortProperty == null)
                    {
                        var reportSort  = new SortProperty();
                        var sortColumns = new Dictionary <string, SortDirection>();
                        foreach (var reportField in report.ReportFields.Where(a => a.SortOrder.HasValue).OrderBy(a => a.SortOrder.Value))
                        {
                            if (reportFieldSortExpressions.ContainsKey(reportField.Guid))
                            {
                                var sortField = reportFieldSortExpressions[reportField.Guid];
                                if (!string.IsNullOrWhiteSpace(sortField))
                                {
                                    sortColumns.Add(sortField, reportField.SortDirection);
                                }
                            }
                        }

                        if (sortColumns.Any())
                        {
                            reportSort.Property = sortColumns.Select(a => a.Key + (a.Value == SortDirection.Descending ? " desc" : string.Empty)).ToList().AsDelimited(",");
                            sortProperty        = reportSort;
                        }
                    }

                    var qryErrors = new List <string>();
                    System.Data.Entity.DbContext reportDbContext;
                    dynamic qry = report.GetQueryable(entityType, selectedEntityFields, selectedAttributes, selectedComponents, sortProperty, dataViewFilterOverrides, databaseTimeoutSeconds ?? 180, isCommunication, out qryErrors, out reportDbContext);
                    errors.AddRange(qryErrors);

                    if (!string.IsNullOrEmpty(report.QueryHint) && reportDbContext is RockContext)
                    {
                        using (new QueryHintScope(reportDbContext as RockContext, report.QueryHint))
                        {
                            gReport.SetLinqDataSource(qry);
                        }
                    }
                    else
                    {
                        gReport.SetLinqDataSource(qry);
                    }

                    gReport.DataBind();
                }
                catch (Exception ex)
                {
                    Exception exception = ex;
                    ExceptionLogService.LogException(ex, HttpContext.Current);
                    while (exception != null)
                    {
                        if (exception is System.Data.SqlClient.SqlException)
                        {
                            // if there was a SQL Server Timeout, have the warning be a friendly message about that.
                            if ((exception as System.Data.SqlClient.SqlException).Number == -2)
                            {
                                errorMessage = "This report did not complete in a timely manner. You can try again or adjust the timeout setting of this block.";
                                return;
                            }
                            else
                            {
                                errors.Add(exception.Message);
                                exception = exception.InnerException;
                            }
                        }
                        else
                        {
                            errors.Add(exception.Message);
                            exception = exception.InnerException;
                        }
                    }
                }

                if (errors.Any())
                {
                    errorMessage = "WARNING: There was a problem with one or more of the report's data components...<br/><br/> " + errors.AsDelimited("<br/>");
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Binds the grid.
        /// </summary>
        /// <param name="report">The report.</param>
        /// <param name="gReport">The g report.</param>
        /// <param name="bindGridOptions">The bind grid options.</param>
        /// <exception cref="ArgumentNullException">Report must be specified</exception>
        /// <exception cref="Rock.Reporting.RockReportingException">Unable to determine EntityType type for {report.EntityType}</exception>
        public static void BindGrid(Report report, Grid gReport, BindGridOptions bindGridOptions)
        {
            if (report == null)
            {
                throw new ArgumentNullException("Report must be specified");
            }

            if (!report.EntityTypeId.HasValue)
            {
                gReport.Visible = false;
                return;
            }

            var currentPerson = bindGridOptions?.CurrentPerson;

            var rockContext = new RockContext();

            if (!report.IsAuthorized(Authorization.VIEW, currentPerson))
            {
                gReport.Visible = false;
                return;
            }

            Type entityType = EntityTypeCache.Get(report.EntityTypeId.Value, rockContext).GetEntityType();

            if (entityType == null)
            {
                throw new RockReportException(report, $"Unable to determine EntityType type for {report.EntityType} ");
            }

            Stopwatch stopwatch = Stopwatch.StartNew();

            gReport.EntityTypeId = report.EntityTypeId;

            bool isPersonDataSet = report.EntityTypeId == EntityTypeCache.Get(typeof(Rock.Model.Person), true, rockContext).Id;

            if (isPersonDataSet)
            {
                gReport.PersonIdField = "Id";
                gReport.DataKeyNames  = new string[] { "Id" };
            }
            else
            {
                gReport.PersonIdField = null;
            }

            if (report.EntityTypeId.HasValue)
            {
                gReport.RowItemText = EntityTypeCache.Get(report.EntityTypeId.Value, rockContext).FriendlyName;
            }

            List <EntityField> entityFields = Rock.Reporting.EntityHelper.GetEntityFields(entityType, true, false);

            var selectedEntityFields = new Dictionary <int, EntityField>();
            var selectedAttributes   = new Dictionary <int, AttributeCache>();
            var selectedComponents   = new Dictionary <int, ReportField>();

            // if there is a selectField, keep it to preserve which items are checked
            var selectField = gReport.Columns.OfType <SelectField>().FirstOrDefault();

            gReport.Columns.Clear();
            int columnIndex = 0;

            if (!string.IsNullOrWhiteSpace(gReport.PersonIdField))
            {
                // if we already had a selectField, use it (to preserve checkbox state)
                gReport.Columns.Add(selectField ?? new SelectField());
                columnIndex++;
            }

            var reportFieldSortExpressions = new Dictionary <Guid, string>();

            gReport.CommunicateMergeFields = new List <string>();
            gReport.CommunicationRecipientPersonIdFields = new List <string>();

            foreach (var reportField in report.ReportFields.OrderBy(a => a.ColumnOrder))
            {
                bool isMergeField     = reportField.IsCommunicationMergeField.HasValue && reportField.IsCommunicationMergeField.Value;
                bool isRecipientField = reportField.IsCommunicationRecipientField.HasValue && reportField.IsCommunicationRecipientField.Value;

                columnIndex++;
                if (reportField.ReportFieldType == ReportFieldType.Property)
                {
                    var entityField = entityFields.FirstOrDefault(a => a.Name == reportField.Selection);

                    if (entityField == null)
                    {
                        // if the reportField selection refers to a non-existant entityField, ignore this field
                        continue;
                    }

                    selectedEntityFields.Add(columnIndex, entityField);

                    BoundField boundField = entityField.GetBoundFieldType();
                    boundField.DataField      = string.Format("Entity_{0}_{1}", entityField.Name, columnIndex);
                    boundField.HeaderText     = string.IsNullOrWhiteSpace(reportField.ColumnHeaderText) ? entityField.Title : reportField.ColumnHeaderText;
                    boundField.SortExpression = boundField.DataField;
                    reportFieldSortExpressions.AddOrReplace(reportField.Guid, boundField.SortExpression);
                    boundField.Visible = reportField.ShowInGrid;
                    gReport.Columns.Add(boundField);

                    if (isMergeField)
                    {
                        gReport.CommunicateMergeFields.Add($"{boundField.DataField}|{boundField.HeaderText.RemoveSpecialCharacters()}");
                    }

                    if (isRecipientField)
                    {
                        gReport.CommunicationRecipientPersonIdFields.Add(boundField.DataField);
                    }
                }
                else if (reportField.ReportFieldType == ReportFieldType.Attribute)
                {
                    Guid?attributeGuid = reportField.Selection.AsGuidOrNull();
                    if (attributeGuid == null)
                    {
                        // if an attribute guid is not specified, just ignore this field
                        continue;
                    }

                    var attribute = AttributeCache.Get(attributeGuid.Value, rockContext);
                    if (attribute == null || !attribute.IsActive)
                    {
                        // if the attribute doesn't exist (or no longer exists), or if the active is not active, just ignore this field
                        continue;
                    }

                    selectedAttributes.Add(columnIndex, attribute);

                    BoundField boundField;

                    if (attribute.FieldType.Guid.Equals(Rock.SystemGuid.FieldType.BOOLEAN.AsGuid()))
                    {
                        boundField = new BoolField();
                    }
                    else if (attribute.FieldType.Guid.Equals(Rock.SystemGuid.FieldType.DEFINED_VALUE.AsGuid()))
                    {
                        boundField = new DefinedValueField();
                    }
                    else
                    {
                        boundField            = new CallbackField();
                        boundField.HtmlEncode = false;
                        (boundField as CallbackField).OnFormatDataValue += (sender, e) =>
                        {
                            string resultHtml     = null;
                            var    attributeValue = e.DataValue ?? attribute.DefaultValueAsType;
                            if (attributeValue != null)
                            {
                                bool condensed = true;
                                resultHtml = attribute.FieldType.Field.FormatValueAsHtml(gReport, attributeValue.ToString(), attribute.QualifierValues, condensed);
                            }

                            e.FormattedValue = resultHtml ?? string.Empty;
                        };
                    }

                    boundField.DataField      = string.Format("Attribute_{0}_{1}", attribute.Id, columnIndex);
                    boundField.HeaderText     = string.IsNullOrWhiteSpace(reportField.ColumnHeaderText) ? attribute.Name : reportField.ColumnHeaderText;
                    boundField.SortExpression = boundField.DataField;
                    reportFieldSortExpressions.AddOrReplace(reportField.Guid, boundField.SortExpression);

                    if (attribute.FieldType.Guid.Equals(Rock.SystemGuid.FieldType.INTEGER.AsGuid()) ||
                        attribute.FieldType.Guid.Equals(Rock.SystemGuid.FieldType.DATE.AsGuid()) ||
                        attribute.FieldType.Guid.Equals(Rock.SystemGuid.FieldType.FILTER_DATE.AsGuid()))
                    {
                        boundField.HeaderStyle.HorizontalAlign = HorizontalAlign.Right;
                        boundField.ItemStyle.HorizontalAlign   = HorizontalAlign.Right;
                    }

                    boundField.Visible = reportField.ShowInGrid;

                    gReport.Columns.Add(boundField);

                    if (isMergeField)
                    {
                        gReport.CommunicateMergeFields.Add($"{boundField.DataField}|{boundField.HeaderText.RemoveSpecialCharacters()}");
                    }

                    if (isRecipientField)
                    {
                        gReport.CommunicationRecipientPersonIdFields.Add(boundField.DataField);
                    }
                }
                else if (reportField.ReportFieldType == ReportFieldType.DataSelectComponent)
                {
                    selectedComponents.Add(columnIndex, reportField);

                    DataSelectComponent selectComponent = DataSelectContainer.GetComponent(reportField.DataSelectComponentEntityType.Name);
                    if (selectComponent == null)
                    {
                        throw new RockReportFieldExpressionException(reportField, $"Unable to determine select component for {reportField.DataSelectComponentEntityType.Name}");
                    }

                    DataControlField columnField = selectComponent.GetGridField(entityType, reportField.Selection ?? string.Empty);
                    string           fieldId     = $"{selectComponent.ColumnPropertyName}_{columnIndex}";

                    if (columnField is BoundField)
                    {
                        (columnField as BoundField).DataField = $"Data_{fieldId}";
                        var  customSortProperties = selectComponent.SortProperties(reportField.Selection ?? string.Empty);
                        bool sortReversed         = selectComponent.SortReversed(reportField.Selection ?? string.Empty);
                        if (customSortProperties != null)
                        {
                            if (customSortProperties == string.Empty)
                            {
                                // disable sorting if customSortExpression set to string.empty
                                columnField.SortExpression = string.Empty;
                            }
                            else
                            {
                                columnField.SortExpression = customSortProperties.Split(',').Select(a => string.Format("Sort_{0}_{1}", a, columnIndex)).ToList().AsDelimited(",");
                            }
                        }
                        else
                        {
                            // use default sorting if customSortExpression was null
                            columnField.SortExpression = (columnField as BoundField).DataField;
                        }

                        if (sortReversed == true && !string.IsNullOrWhiteSpace(columnField.SortExpression))
                        {
                            columnField.SortExpression = columnField.SortExpression + " DESC";
                        }
                    }

                    columnField.HeaderText = string.IsNullOrWhiteSpace(reportField.ColumnHeaderText) ? selectComponent.ColumnHeaderText : reportField.ColumnHeaderText;
                    if (!string.IsNullOrEmpty(columnField.SortExpression))
                    {
                        reportFieldSortExpressions.AddOrReplace(reportField.Guid, columnField.SortExpression);
                    }

                    columnField.Visible = reportField.ShowInGrid;
                    gReport.Columns.Add(columnField);

                    if (isMergeField)
                    {
                        gReport.CommunicateMergeFields.Add($"Data_{fieldId}|{columnField.HeaderText.RemoveSpecialCharacters()}");
                    }
                    if (isRecipientField)
                    {
                        string fieldName = (selectComponent is IRecipientDataSelect) ? $"Recipient_{fieldId}" : $"Data_{fieldId}";
                        gReport.CommunicationRecipientPersonIdFields.Add(fieldName);
                    }
                }
            }

            // if no fields are specified, show the default fields (Previewable/All) for the EntityType
            var dataColumns = gReport.Columns.OfType <object>().Where(a => a.GetType() != typeof(SelectField));

            if (dataColumns.Count() == 0)
            {
                // show either the Previewable Columns or all (if there are no previewable columns)
                bool showAllColumns = !entityFields.Any(a => a.FieldKind == FieldKind.Property && a.IsPreviewable);
                foreach (var entityField in entityFields.Where(a => a.FieldKind == FieldKind.Property))
                {
                    columnIndex++;
                    selectedEntityFields.Add(columnIndex, entityField);

                    BoundField boundField = entityField.GetBoundFieldType();

                    boundField.DataField      = string.Format("Entity_{0}_{1}", entityField.Name, columnIndex);
                    boundField.HeaderText     = entityField.Name;
                    boundField.SortExpression = boundField.DataField;
                    boundField.Visible        = showAllColumns || entityField.IsPreviewable;
                    gReport.Columns.Add(boundField);
                }
            }

            try
            {
                gReport.Visible        = true;
                gReport.ExportFilename = report.Name;
                SortProperty sortProperty = gReport.SortProperty;
                if (sortProperty == null)
                {
                    var reportSort  = new SortProperty();
                    var sortColumns = new Dictionary <string, SortDirection>();
                    foreach (var reportField in report.ReportFields.Where(a => a.SortOrder.HasValue).OrderBy(a => a.SortOrder.Value))
                    {
                        if (reportFieldSortExpressions.ContainsKey(reportField.Guid))
                        {
                            var sortField = reportFieldSortExpressions[reportField.Guid];
                            if (!string.IsNullOrWhiteSpace(sortField))
                            {
                                sortColumns.Add(sortField, reportField.SortDirection);
                            }
                        }
                    }

                    if (sortColumns.Any())
                    {
                        reportSort.Property = sortColumns.Select(a => a.Key + (a.Value == SortDirection.Descending ? " desc" : string.Empty)).ToList().AsDelimited(",");
                        sortProperty        = reportSort;
                    }
                }

                var qryErrors       = new List <string>();
                var reportDbContext = bindGridOptions?.ReportDbContext;
                if (reportDbContext == null)
                {
                    reportDbContext = Reflection.GetDbContextForEntityType(entityType);
                }

                ReportGetQueryableArgs reportGetQueryableArgs = new ReportGetQueryableArgs
                {
                    ReportDbContext         = reportDbContext as Rock.Data.DbContext,
                    EntityFields            = selectedEntityFields,
                    Attributes              = selectedAttributes,
                    SelectComponents        = selectedComponents,
                    SortProperty            = sortProperty,
                    DataViewFilterOverrides = bindGridOptions?.DataViewFilterOverrides,
                    DatabaseTimeoutSeconds  = bindGridOptions?.DatabaseTimeoutSeconds ?? 180,
                    IsCommunication         = bindGridOptions?.IsCommunication ?? false
                };

                dynamic qry = report.GetQueryable(reportGetQueryableArgs);

                if (!string.IsNullOrEmpty(report.QueryHint) && reportDbContext is RockContext)
                {
                    using (new QueryHintScope(reportDbContext as RockContext, report.QueryHint))
                    {
                        gReport.SetLinqDataSource(qry);
                    }
                }
                else
                {
                    gReport.SetLinqDataSource(qry);
                }

                gReport.DataBind();
                stopwatch.Stop();

                ReportService.AddRunReportTransaction(report.Id, Convert.ToInt32(stopwatch.Elapsed.TotalMilliseconds));
            }
            catch (Exception ex)
            {
                Exception exception = ex;
                ExceptionLogService.LogException(ex, HttpContext.Current);

                // recursively find if there was a SQL timeout exception.
                // A SQL Timeout would be something we might expect, so we'll give that a friendly error message.
                var sqlTimeoutException = FindSqlTimeoutException(ex);

                if (sqlTimeoutException != null)
                {
                    // if there was a SQL Server Timeout, have the warning be a friendly message about that.
                    throw new RockReportException(report, "This report did not complete in a timely manner. You can try again or adjust the timeout setting of this block.", ex);
                }

                // if there isn't a SQL Exception, we'll throw the original exception (since it would be an exception that we wouldn't expect)
                throw;
            }
        }