/// <summary> /// Gets the queryable. /// </summary> /// <param name="entityType">Type of the entity.</param> /// <param name="entityFields">The entity fields.</param> /// <param name="attributes">The attributes.</param> /// <param name="selectComponents">The select components.</param> /// <param name="sortProperty">The sort property.</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="errorMessages">The error messages.</param> /// <param name="reportDbContext">The report database context.</param> /// <returns></returns> /// <exception cref="Exception"></exception> public IQueryable GetQueryable(Type entityType, Dictionary <int, EntityField> entityFields, Dictionary <int, AttributeCache> attributes, Dictionary <int, ReportField> selectComponents, Rock.Web.UI.Controls.SortProperty sortProperty, DataViewFilterOverrides dataViewFilterOverrides, int?databaseTimeoutSeconds, bool isCommunication, out List <string> errorMessages, out System.Data.Entity.DbContext reportDbContext) { errorMessages = new List <string>(); reportDbContext = null; if (entityType != null) { reportDbContext = Reflection.GetDbContextForEntityType(entityType); IService serviceInstance = Reflection.GetServiceForEntityType(entityType, reportDbContext); if (databaseTimeoutSeconds.HasValue) { reportDbContext.Database.CommandTimeout = databaseTimeoutSeconds.Value; } if (serviceInstance != null) { ParameterExpression paramExpression = serviceInstance.ParameterExpression; MemberExpression idExpression = Expression.Property(paramExpression, "Id"); // Get AttributeValue queryable and parameter var attributeValues = reportDbContext.Set <AttributeValue>(); ParameterExpression attributeValueParameter = Expression.Parameter(typeof(AttributeValue), "v"); // Create the dynamic type var dynamicFields = new Dictionary <string, Type>(); dynamicFields.Add("Id", typeof(int)); foreach (var f in entityFields) { dynamicFields.Add(string.Format("Entity_{0}_{1}", f.Value.Name, f.Key), f.Value.PropertyType); } foreach (var a in attributes) { dynamicFields.Add(string.Format("Attribute_{0}_{1}", a.Value.Id, a.Key), a.Value.FieldType.Field.AttributeValueFieldType); } foreach (var reportField in selectComponents) { DataSelectComponent selectComponent = DataSelectContainer.GetComponent(reportField.Value.DataSelectComponentEntityType.Name); if (selectComponent != null) { dynamicFields.Add(string.Format("Data_{0}_{1}", selectComponent.ColumnPropertyName, reportField.Key), selectComponent.ColumnFieldType); var customSortProperties = selectComponent.SortProperties(reportField.Value.Selection); if (customSortProperties != null) { foreach (var customSortProperty in customSortProperties.Split(',')) { if (!string.IsNullOrWhiteSpace(customSortProperty)) { var customSortPropertyType = entityType.GetPropertyType(customSortProperty); dynamicFields.Add(string.Format("Sort_{0}_{1}", customSortProperty, reportField.Key), customSortPropertyType ?? typeof(string)); } } } if (isCommunication && selectComponent is IRecipientDataSelect) { dynamicFields.Add($"Recipient_{selectComponent.ColumnPropertyName}_{reportField.Key}", ((IRecipientDataSelect)selectComponent).RecipientColumnFieldType); } } } if (dynamicFields.Count == 0) { errorMessages.Add("At least one field must be defined"); return(null); } Type dynamicType = LinqRuntimeTypeBuilder.GetDynamicType(dynamicFields); ConstructorInfo methodFromHandle = dynamicType.GetConstructor(Type.EmptyTypes); // Bind the dynamic fields to their expressions var bindings = new List <MemberAssignment>(); bindings.Add(Expression.Bind(dynamicType.GetField("id"), idExpression)); foreach (var f in entityFields) { bindings.Add(Expression.Bind(dynamicType.GetField(string.Format("entity_{0}_{1}", f.Value.Name, f.Key)), Expression.Property(paramExpression, f.Value.Name))); } foreach (var a in attributes) { bindings.Add(Expression.Bind(dynamicType.GetField(string.Format("attribute_{0}_{1}", a.Value.Id, a.Key)), GetAttributeValueExpression(attributeValues, attributeValueParameter, idExpression, a.Value.Id))); } foreach (var reportField in selectComponents) { DataSelectComponent selectComponent = DataSelectContainer.GetComponent(reportField.Value.DataSelectComponentEntityType.Name); if (selectComponent != null) { try { var componentExpression = selectComponent.GetExpression(reportDbContext, idExpression, reportField.Value.Selection ?? string.Empty); if (componentExpression == null) { componentExpression = Expression.Constant(null, typeof(string)); } bindings.Add(Expression.Bind(dynamicType.GetField(string.Format("data_{0}_{1}", selectComponent.ColumnPropertyName, reportField.Key)), componentExpression)); if (isCommunication && selectComponent is IRecipientDataSelect) { var recipientPersonIdExpression = ((IRecipientDataSelect)selectComponent).GetRecipientPersonIdExpression(reportDbContext, idExpression, reportField.Value.Selection ?? string.Empty); if (recipientPersonIdExpression != null) { bindings.Add(Expression.Bind(dynamicType.GetField(string.Format("recipient_{0}_{1}", selectComponent.ColumnPropertyName, reportField.Key)), recipientPersonIdExpression)); } } var customSortProperties = selectComponent.SortProperties(reportField.Value.Selection); if (!string.IsNullOrEmpty(customSortProperties)) { foreach (var customSortProperty in customSortProperties.Split(',')) { var customSortPropertyParts = customSortProperty.Split('.'); MemberInfo memberInfo = dynamicType.GetField(string.Format("sort_{0}_{1}", customSortProperty, reportField.Key)); Expression memberExpression = null; foreach (var customSortPropertyPart in customSortPropertyParts) { memberExpression = Expression.Property(memberExpression ?? paramExpression, customSortPropertyPart); } bindings.Add(Expression.Bind(memberInfo, memberExpression)); } } } catch (Exception ex) { throw new Exception(string.Format("Exception in {0}", selectComponent), ex); } } } ConstructorInfo constructorInfo = dynamicType.GetConstructor(Type.EmptyTypes); NewExpression newExpression = Expression.New(constructorInfo); MemberInitExpression memberInitExpression = Expression.MemberInit(newExpression, bindings); LambdaExpression selector = Expression.Lambda(memberInitExpression, paramExpression); // NOTE: having a NULL Dataview is OK. Expression whereExpression = null; if (this.DataView != null) { whereExpression = this.DataView.GetExpression(serviceInstance, paramExpression, dataViewFilterOverrides, out errorMessages); } MethodInfo getMethod = serviceInstance.GetType().GetMethod("Get", new Type[] { typeof(ParameterExpression), typeof(Expression), typeof(Rock.Web.UI.Controls.SortProperty), typeof(int?) }); if (getMethod != null) { var getResult = getMethod.Invoke(serviceInstance, new object[] { paramExpression, whereExpression, null, null }); var qry = getResult as IQueryable <IEntity>; var qryExpression = qry.Expression; // apply the OrderBy clauses to the Expression from whatever columns are specified in sortProperty.Property string orderByMethod = "OrderBy"; if (sortProperty == null) { // if no sorting was specified, sort by Id sortProperty = new Web.UI.Controls.SortProperty { Direction = SortDirection.Ascending, Property = "Id" }; } /* * NOTE: The sort property sorting rules can be a little confusing. Here is how it works: * - SortProperty.Direction of Ascending means sort exactly as what the Columns specification says * - SortProperty.Direction of Descending means sort the _opposite_ of what the Columns specification says * Examples: * 1) SortProperty.Property "LastName desc, FirstName, BirthDate desc" and SortProperty.Direction = Ascending * OrderBy should be: "order by LastName desc, FirstName, BirthDate desc" * 2) SortProperty.Property "LastName desc, FirstName, BirthDate desc" and SortProperty.Direction = Descending * OrderBy should be: "order by LastName, FirstName desc, BirthDate" */ foreach (var column in sortProperty.Property.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) { string propertyName; var direction = sortProperty.Direction; if (column.EndsWith(" desc", StringComparison.OrdinalIgnoreCase)) { propertyName = column.Left(column.Length - 5); // if the column ends with " desc", toggle the direction if sortProperty is Descending direction = sortProperty.Direction == SortDirection.Ascending ? SortDirection.Descending : SortDirection.Ascending; } else { propertyName = column; } string methodName = direction == SortDirection.Descending ? orderByMethod + "Descending" : orderByMethod; // Call OrderBy on whatever the Expression is for that Column var sortMember = bindings.FirstOrDefault(a => a.Member.Name.Equals(propertyName, StringComparison.OrdinalIgnoreCase)); LambdaExpression sortSelector = Expression.Lambda(sortMember.Expression, paramExpression); qryExpression = Expression.Call(typeof(Queryable), methodName, new Type[] { qry.ElementType, sortSelector.ReturnType }, qryExpression, sortSelector); orderByMethod = "ThenBy"; } var selectExpression = Expression.Call(typeof(Queryable), "Select", new Type[] { qry.ElementType, dynamicType }, qryExpression, selector); var query = qry.Provider.CreateQuery(selectExpression).AsNoTracking(); // cast to a dynamic so that we can do a Queryable.Take (the compiler figures out the T in IQueryable at runtime) dynamic dquery = query; if (FetchTop.HasValue) { dquery = Queryable.Take(dquery, FetchTop.Value); } return(dquery as IQueryable); } } } return(null); }
/// <summary> /// Gets the data source. /// </summary> /// <param name="context">The context.</param> /// <param name="entityType">Type of the entity.</param> /// <param name="entityFields">The entity fields.</param> /// <param name="attributes">The attributes.</param> /// <param name="selectComponents">The select components.</param> /// <param name="sortProperty">The sort property.</param> /// <param name="errorMessages">The error messages.</param> /// <returns></returns> public List <object> GetDataSource(RockContext context, Type entityType, Dictionary <int, EntityField> entityFields, Dictionary <int, AttributeCache> attributes, Dictionary <int, ReportField> selectComponents, Rock.Web.UI.Controls.SortProperty sortProperty, out List <string> errorMessages) { errorMessages = new List <string>(); if (entityType != null) { Type[] modelType = { entityType }; Type genericServiceType = typeof(Rock.Data.Service <>); Type modelServiceType = genericServiceType.MakeGenericType(modelType); object serviceInstance = Activator.CreateInstance(modelServiceType, new object[] { context }); if (serviceInstance != null) { ParameterExpression paramExpression = serviceInstance.GetType().GetProperty("ParameterExpression").GetValue(serviceInstance) as ParameterExpression; MemberExpression idExpression = Expression.Property(paramExpression, "Id"); // Get AttributeValue queryable and parameter var attributeValues = context.Set <AttributeValue>(); ParameterExpression attributeValueParameter = Expression.Parameter(typeof(AttributeValue), "v"); // Create the dynamic type var dynamicFields = new Dictionary <string, Type>(); foreach (var f in entityFields) { dynamicFields.Add(string.Format("Entity_{0}_{1}", f.Value.Name, f.Key), f.Value.PropertyType); } foreach (var a in attributes) { dynamicFields.Add(string.Format("Attribute_{0}_{1}", a.Value.Id, a.Key), typeof(string)); } foreach (var reportField in selectComponents) { DataSelectComponent selectComponent = DataSelectContainer.GetComponent(reportField.Value.DataSelectComponentEntityType.Name); if (selectComponent != null) { dynamicFields.Add(string.Format("Data_{0}_{1}", selectComponent.ColumnPropertyName, reportField.Key), selectComponent.ColumnFieldType); } } if (dynamicFields.Count == 0) { errorMessages.Add("At least one field must be defined"); return(null); } Type dynamicType = LinqRuntimeTypeBuilder.GetDynamicType(dynamicFields); ConstructorInfo methodFromHandle = dynamicType.GetConstructor(Type.EmptyTypes); // Bind the dynamic fields to their expressions var bindings = new List <MemberBinding>(); foreach (var f in entityFields) { bindings.Add(Expression.Bind(dynamicType.GetField(string.Format("entity_{0}_{1}", f.Value.Name, f.Key)), Expression.Property(paramExpression, f.Value.Name))); } foreach (var a in attributes) { bindings.Add(Expression.Bind(dynamicType.GetField(string.Format("attribute_{0}_{1}", a.Value.Id, a.Key)), GetAttributeValueExpression(attributeValues, attributeValueParameter, idExpression, a.Value.Id))); } foreach (var reportField in selectComponents) { DataSelectComponent selectComponent = DataSelectContainer.GetComponent(reportField.Value.DataSelectComponentEntityType.Name); if (selectComponent != null) { bindings.Add(Expression.Bind(dynamicType.GetField(string.Format("data_{0}_{1}", selectComponent.ColumnPropertyName, reportField.Key)), selectComponent.GetExpression(context, idExpression, reportField.Value.Selection))); } } ConstructorInfo constructorInfo = dynamicType.GetConstructor(Type.EmptyTypes); NewExpression newExpression = Expression.New(constructorInfo); MemberInitExpression memberInitExpression = Expression.MemberInit(newExpression, bindings); Expression selector = Expression.Lambda(memberInitExpression, paramExpression); Expression whereExpression = this.DataView.GetExpression(serviceInstance, paramExpression, out errorMessages); MethodInfo getMethod = serviceInstance.GetType().GetMethod("Get", new Type[] { typeof(ParameterExpression), typeof(Expression), typeof(Rock.Web.UI.Controls.SortProperty) }); if (getMethod != null) { var getResult = getMethod.Invoke(serviceInstance, new object[] { paramExpression, whereExpression, sortProperty }); var qry = getResult as IQueryable <IEntity>; var selectExpression = Expression.Call(typeof(Queryable), "Select", new Type[] { qry.ElementType, dynamicType }, Expression.Constant(qry), selector); var query = qry.Provider.CreateQuery(selectExpression).AsNoTracking(); // enumerate thru the query results and put into a list var reportResult = new List <object>(); var enumerator = query.GetEnumerator(); while (enumerator.MoveNext()) { reportResult.Add(enumerator.Current); } return(reportResult); } } } return(null); }
/// <summary> /// Shows the preview. /// </summary> /// <param name="entityTypeId">The entity type id.</param> /// <param name="filter">The filter.</param> private void BindGrid(Report report) { if (report != null && report.DataView != null) { var errors = new List <string>(); if (!report.EntityTypeId.HasValue) { return; } Type entityType = EntityTypeCache.Read(report.EntityTypeId.Value).GetEntityType(); List <EntityField> entityFields = Rock.Reporting.EntityHelper.GetEntityFields(entityType); var selectedEntityFields = new Dictionary <int, EntityField>(); var selectedAttributes = new Dictionary <int, AttributeCache>(); var selectedComponents = new Dictionary <int, ReportField>(); gReport.Columns.Clear(); int columnIndex = 0; foreach (var reportField in report.ReportFields.OrderBy(a => a.Order)) { columnIndex++; if (reportField.ReportFieldType == ReportFieldType.Property) { var entityField = entityFields.FirstOrDefault(a => a.Name == reportField.Selection); if (entityField != null) { selectedEntityFields.Add(columnIndex, entityField); if (reportField.ShowInGrid) { BoundField boundField; if (entityField.DefinedTypeId.HasValue) { boundField = new DefinedValueField(); } else { boundField = Grid.GetGridField(entityField.PropertyType); } boundField.DataField = string.Format("Entity_{0}_{1}", entityField.Name, columnIndex); boundField.HeaderText = string.IsNullOrWhiteSpace(reportField.ColumnHeaderText) ? entityField.Title : reportField.ColumnHeaderText; boundField.SortExpression = entityField.Name; gReport.Columns.Add(boundField); } } } else if (reportField.ReportFieldType == ReportFieldType.Attribute) { int?attributeId = reportField.Selection.AsInteger(false); if (attributeId.HasValue) { var attribute = AttributeCache.Read(attributeId.Value); selectedAttributes.Add(columnIndex, attribute); if (reportField.ShowInGrid) { BoundField boundField; if (attribute.FieldType.Guid.Equals(Rock.SystemGuid.FieldType.BOOLEAN.AsGuid())) { boundField = new BoolField(); } else { boundField = new BoundField(); } boundField.DataField = string.Format("Attribute_{0}_{1}", attribute.Id, columnIndex); boundField.HeaderText = string.IsNullOrWhiteSpace(reportField.ColumnHeaderText) ? attribute.Name : reportField.ColumnHeaderText; boundField.SortExpression = null; if (attribute.FieldType.Guid.Equals(Rock.SystemGuid.FieldType.INTEGER.AsGuid()) || attribute.FieldType.Guid.Equals(Rock.SystemGuid.FieldType.DATE.AsGuid())) { boundField.HeaderStyle.HorizontalAlign = HorizontalAlign.Right; boundField.ItemStyle.HorizontalAlign = HorizontalAlign.Right; } // NOTE: Additional formatting for attributes is done in the gReport_RowDataBound event gReport.Columns.Add(boundField); } } } else if (reportField.ReportFieldType == ReportFieldType.DataSelectComponent) { selectedComponents.Add(columnIndex, reportField); if (reportField.ShowInGrid) { DataSelectComponent selectComponent = DataSelectContainer.GetComponent(reportField.DataSelectComponentEntityType.Name); if (selectComponent != null) { var boundField = Grid.GetGridField(selectComponent.ColumnFieldType); boundField.DataField = string.Format("Data_{0}_{1}", selectComponent.ColumnPropertyName, columnIndex); boundField.HeaderText = string.IsNullOrWhiteSpace(reportField.ColumnHeaderText) ? selectComponent.ColumnHeaderText : reportField.ColumnHeaderText; boundField.SortExpression = null; gReport.Columns.Add(boundField); } } } } gReport.DataSource = report.GetDataSource(new RockContext(), entityType, selectedEntityFields, selectedAttributes, selectedComponents, gReport.SortProperty, out errors); if (errors.Any()) { nbEditModeMessage.Text = "INFO: There was a problem with one or more of the report's data components...<br/><br/> " + errors.AsDelimited("<br/>"); } gReport.DataBind(); } }
/// <summary> /// Adds the field panel widget. /// </summary> /// <param name="reportFieldGuid">The report field unique identifier.</param> /// <param name="reportFieldType">Type of the report field.</param> /// <param name="fieldSelection">The field selection.</param> /// <param name="showExpanded">if set to <c>true</c> [show expanded].</param> /// <param name="setReportFieldValues">if set to <c>true</c> [set report field values].</param> /// <param name="reportField">The report field.</param> private void AddFieldPanelWidget(Guid reportFieldGuid, ReportFieldType reportFieldType, string fieldSelection, bool showExpanded, bool setReportFieldValues = false, ReportField reportField = null) { int entityTypeId = ddlEntityType.SelectedValueAsInt() ?? 0; if (entityTypeId == 0) { return; } PanelWidget panelWidget = new PanelWidget(); panelWidget.ID = string.Format("reportFieldWidget_{0}", reportFieldGuid.ToString("N")); string fieldTitle = null; DataSelectComponent dataSelectComponent = null; switch (reportFieldType) { case ReportFieldType.Property: var entityType = EntityTypeCache.Read(entityTypeId).GetEntityType(); var entityField = EntityHelper.GetEntityFields(entityType).FirstOrDefault(a => a.Name == fieldSelection); if (entityField != null) { fieldTitle = entityField.Title; } break; case ReportFieldType.Attribute: var attribute = AttributeCache.Read(fieldSelection.AsInteger() ?? 0); if (attribute != null) { fieldTitle = attribute.Name; } break; case ReportFieldType.DataSelectComponent: string dataSelectComponentTypeName = EntityTypeCache.Read(fieldSelection.AsInteger() ?? 0).GetEntityType().FullName; dataSelectComponent = Rock.Reporting.DataSelectContainer.GetComponent(dataSelectComponentTypeName); if (dataSelectComponent != null) { fieldTitle = dataSelectComponent.GetTitle(null); } break; } if (fieldTitle == null) { // return if we can't determine field return; } panelWidget.Title = fieldTitle; panelWidget.ShowDeleteButton = true; panelWidget.DeleteClick += FieldsPanelWidget_DeleteClick; panelWidget.ShowReorderIcon = true; panelWidget.Expanded = showExpanded; HiddenField hfReportFieldType = new HiddenField(); hfReportFieldType.ID = panelWidget.ID + "_hfReportFieldType"; hfReportFieldType.Value = reportFieldType.ConvertToString(); panelWidget.Controls.Add(hfReportFieldType); HiddenField hfFieldSelection = new HiddenField(); hfFieldSelection.ID = panelWidget.ID + "_hfFieldSelection"; hfFieldSelection.Value = fieldSelection; panelWidget.Controls.Add(hfFieldSelection); RockCheckBox showInGridCheckBox = new RockCheckBox(); showInGridCheckBox.ID = panelWidget.ID + "_showInGridCheckBox"; showInGridCheckBox.Text = "Show in Grid"; if (setReportFieldValues) { showInGridCheckBox.Checked = reportField.ShowInGrid; } panelWidget.Controls.Add(showInGridCheckBox); RockTextBox columnHeaderTextTextBox = new RockTextBox(); columnHeaderTextTextBox.ID = panelWidget.ID + "_columnHeaderTextTextBox"; columnHeaderTextTextBox.Label = "Column Label"; if (setReportFieldValues) { columnHeaderTextTextBox.Text = string.IsNullOrWhiteSpace(reportField.ColumnHeaderText) ? fieldTitle : reportField.ColumnHeaderText; } panelWidget.Controls.Add(columnHeaderTextTextBox); if (dataSelectComponent != null) { PlaceHolder phDataSelectControls = new PlaceHolder(); phDataSelectControls.ID = panelWidget.ID + "_phDataSelectControls"; panelWidget.Controls.Add(phDataSelectControls); var dataSelectControls = dataSelectComponent.CreateChildControls(phDataSelectControls); if (setReportFieldValues) { dataSelectComponent.SetSelection(dataSelectControls, reportField.Selection); } } phReportFields.Controls.Add(panelWidget); }
/// <summary> /// Handles the Click event of the btnSave control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param> protected void btnSave_Click(object sender, EventArgs e) { Report report = null; using (new UnitOfWorkScope()) { ReportService service = new ReportService(); ReportFieldService reportFieldService = new ReportFieldService(); int reportId = int.Parse(hfReportId.Value); if (reportId == 0) { report = new Report(); report.IsSystem = false; } else { report = service.Get(reportId); } report.Name = tbName.Text; report.Description = tbDescription.Text; report.CategoryId = cpCategory.SelectedValueAsInt(); report.EntityTypeId = ddlEntityType.SelectedValueAsInt(); report.DataViewId = ddlDataView.SelectedValueAsInt(); if (!Page.IsValid) { return; } if (!report.IsValid) { // Controls will render the error messages return; } RockTransactionScope.WrapTransaction(() => { // delete all the reportFields so we can cleanly add them foreach (var reportField in report.ReportFields.ToList()) { var field = reportFieldService.Get(reportField.Guid); reportFieldService.Delete(field, this.CurrentPersonId); reportFieldService.Save(field, this.CurrentPersonId); } report.ReportFields.Clear(); var allPanelWidgets = phReportFields.ControlsOfTypeRecursive <PanelWidget>(); int displayOrder = 0; foreach (var panelWidget in allPanelWidgets) { string hfReportFieldTypeID = panelWidget.ID + "_hfReportFieldType"; HiddenField hfReportFieldType = phReportFields.ControlsOfTypeRecursive <HiddenField>().First(a => a.ID == hfReportFieldTypeID); string hfFieldSelectionID = panelWidget.ID + "_hfFieldSelection"; HiddenField hfFieldSelection = phReportFields.ControlsOfTypeRecursive <HiddenField>().First(a => a.ID == hfFieldSelectionID); ReportFieldType reportFieldType = hfReportFieldType.Value.ConvertToEnum <ReportFieldType>(); string fieldSelection = hfFieldSelection.Value; ReportField reportField = new ReportField(); reportField.ReportFieldType = reportFieldType; string showInGridCheckBoxId = string.Format("{0}_showInGridCheckBox", panelWidget.ID); RockCheckBox showInGridCheckBox = phReportFields.ControlsOfTypeRecursive <RockCheckBox>().First(a => a.ID == showInGridCheckBoxId); reportField.ShowInGrid = showInGridCheckBox.Checked; string columnHeaderTextTextBoxId = string.Format("{0}_columnHeaderTextTextBox", panelWidget.ID); RockTextBox columnHeaderTextTextBox = phReportFields.ControlsOfTypeRecursive <RockTextBox>().First(a => a.ID == columnHeaderTextTextBoxId); reportField.ColumnHeaderText = columnHeaderTextTextBox.Text; reportField.Order = displayOrder++; if (reportFieldType == ReportFieldType.DataSelectComponent) { reportField.DataSelectComponentEntityTypeId = fieldSelection.AsInteger(); string dataSelectComponentTypeName = EntityTypeCache.Read(reportField.DataSelectComponentEntityTypeId ?? 0).GetEntityType().FullName; DataSelectComponent dataSelectComponent = Rock.Reporting.DataSelectContainer.GetComponent(dataSelectComponentTypeName); string placeHolderId = string.Format("{0}_phDataSelectControls", panelWidget.ID); var placeHolder = phReportFields.ControlsOfTypeRecursive <PlaceHolder>().Where(a => a.ID == placeHolderId).FirstOrDefault(); reportField.Selection = dataSelectComponent.GetSelection(placeHolder.Controls.OfType <Control>().ToArray()); } else { reportField.Selection = fieldSelection; } report.ReportFields.Add(reportField); } if (report.Id.Equals(0)) { service.Add(report, CurrentPersonId); } service.Save(report, CurrentPersonId); }); } var qryParams = new Dictionary <string, string>(); qryParams["ReportId"] = report.Id.ToString(); NavigateToPage(RockPage.Guid, qryParams); }