/// <summary> /// Determines whether the filter's comparison type and filter compare value(s) evaluates to true for the specified value /// </summary> /// <param name="filterValues">The filter values.</param> /// <param name="value">The value.</param> /// <returns> /// <c>true</c> if [is compared to value] [the specified filter values]; otherwise, <c>false</c>. /// </returns> public override bool IsComparedToValue(List <string> filterValues, string value) { if (filterValues == null || filterValues.Count < 2) { return(false); } ComparisonType?filterComparisonType = filterValues[0].ConvertToEnumOrNull <ComparisonType>(); ComparisonType?equalToCompareValue = GetEqualToCompareValue().ConvertToEnumOrNull <ComparisonType>(); DateTime? valueAsDateTime = value.AsDateTime(); // uses Tab Delimited since slidingDateRangePicker is | delimited var filterValueValues = filterValues[1].Split(new string[] { "\t" }, StringSplitOptions.None); // Parse for RelativeValue of DateTime (if specified) filterValueValues[0] = ParseRelativeValue(filterValueValues[0]); DateTime?filterValueAsDateTime1; DateTime?filterValueAsDateTime2 = null; if (filterComparisonType == ComparisonType.Between) { var dateRange = SlidingDateRangePicker.CalculateDateRangeFromDelimitedValues(filterValueValues[1]); filterValueAsDateTime1 = dateRange.Start; filterValueAsDateTime2 = dateRange.End; } else { filterValueAsDateTime1 = filterValueValues[0].AsDateTime(); filterValueAsDateTime2 = null; } return(ComparisonHelper.CompareNumericValues(filterComparisonType.Value, valueAsDateTime?.Ticks, filterValueAsDateTime1?.Ticks, filterValueAsDateTime2?.Ticks)); }
/// <summary> /// Gets a filter expression to be used as part of a AttributeValue Query or EntityAttributeQueryExpression /// </summary> /// <param name="configurationValues">The configuration values.</param> /// <param name="filterValues">The filter values.</param> /// <param name="parameterExpression">The parameter expression.</param> /// <returns></returns> public virtual Expression AttributeFilterExpression(Dictionary <string, ConfigurationValue> configurationValues, List <string> filterValues, ParameterExpression parameterExpression) { if (filterValues.Count >= 2) { ComparisonType?comparisonType = filterValues[0].ConvertToEnumOrNull <ComparisonType>(); if (comparisonType.HasValue) { string compareToValue = filterValues[1]; bool valueNotNeeded = (ComparisonType.IsBlank | ComparisonType.IsNotBlank).HasFlag(comparisonType); if (valueNotNeeded || !string.IsNullOrWhiteSpace(compareToValue)) { MemberExpression propertyExpression = Expression.Property(parameterExpression, this.AttributeValueFieldName); return(ComparisonHelper.ComparisonExpression(comparisonType.Value, propertyExpression, AttributeConstantExpression(compareToValue))); } } else { // No comparison type specified, so return NoAttributeFilterExpression ( which means don't filter ) return(new NoAttributeFilterExpression()); } } // return null if there isn't an additional expression that will help narrow down which AttributeValue records to include return(null); }
/// <summary> /// Gets a filter expression for an attribute value. /// </summary> /// <param name="configurationValues">The configuration values.</param> /// <param name="filterValues">The filter values.</param> /// <param name="parameterExpression">The parameter expression.</param> /// <returns></returns> public override Expression AttributeFilterExpression(Dictionary <string, ConfigurationValue> configurationValues, List <string> filterValues, ParameterExpression parameterExpression) { Expression comparison = null; if (filterValues.Count > 1) { ComparisonType?comparisonType = filterValues[0].ConvertToEnumOrNull <ComparisonType>(); if (comparisonType.HasValue) { string compareToValue = filterValues[1]; MemberExpression propertyExpression = Expression.Property(parameterExpression, this.AttributeValueFieldName); if (!string.IsNullOrWhiteSpace(compareToValue)) { List <string> selectedValues = compareToValue.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList(); foreach (var selectedValue in selectedValues) { var searchValue = "," + selectedValue + ","; var qryToExtract = new AttributeValueService(new Data.RockContext()).Queryable().Where(a => ("," + a.Value + ",").Contains(searchValue)); var valueExpression = FilterExpressionExtractor.Extract <AttributeValue>(qryToExtract, parameterExpression, "a"); if (comparisonType.Value != ComparisonType.Contains) { valueExpression = Expression.Not(valueExpression); } if (comparison == null) { comparison = valueExpression; } else { comparison = Expression.Or(comparison, valueExpression); } } } else { // No comparison value was specified, so we can filter if the Comparison Type using no value still makes sense if ((ComparisonType.IsBlank | ComparisonType.IsNotBlank).HasFlag(comparisonType)) { // Just checking if IsBlank or IsNotBlank, so let ComparisonExpression do its thing return(ComparisonHelper.ComparisonExpression(comparisonType.Value, propertyExpression, AttributeConstantExpression(string.Empty))); } } } } if (comparison == null) { return(new Rock.Data.NoAttributeFilterExpression()); } return(comparison); }
/// <summary> /// Set the property values parsed from a settings string. /// </summary> /// <param name="version">The version number of the parameter set.</param> /// <param name="parameters">An ordered collection of strings representing the parameter values.</param> protected override void OnSetParameters(int version, IReadOnlyList <string> parameters) { // Parameter 1: Group Member Data View GroupMemberDataViewGuid = DataComponentSettingsHelper.GetParameterOrEmpty(parameters, 0).AsGuidOrNull(); // Parameter 2: Group Member Count Comparison Type MemberCountComparison = DataComponentSettingsHelper.GetParameterAsEnum(parameters, 1, ComparisonType.GreaterThan); // Parameter 3: Group Member Count MemberCount = DataComponentSettingsHelper.GetParameterOrEmpty(parameters, 2).AsIntegerOrNull(); }
/// <summary> /// Gets a filter expression to be used as part of a AttributeValue Query or EntityAttributeQueryExpression /// </summary> /// <param name="configurationValues">The configuration values.</param> /// <param name="filterValues">The filter values: FieldName, <see cref="ComparisonType">Comparison Type</see>, (optional) Comparison Value(s)</param> /// <param name="parameterExpression">The parameter expression.</param> /// <returns></returns> public virtual Expression AttributeFilterExpression(Dictionary <string, ConfigurationValue> configurationValues, List <string> filterValues, ParameterExpression parameterExpression) { // If filterValues.Count >= 2, then filterValues[0] is ComparisonType, and filterValues[1] is a CompareToValue. Otherwise, filterValues[0] is a CompareToValue (for example, a SingleSelect attribute) if (filterValues.Count >= 2) { ComparisonType?comparisonType = filterValues[0].ConvertToEnumOrNull <ComparisonType>(); if (comparisonType.HasValue) { string compareToValue = filterValues[1]; MemberExpression propertyExpression = Expression.Property(parameterExpression, this.AttributeValueFieldName); if (!string.IsNullOrWhiteSpace(compareToValue)) { // both a comparison type and value are specified, so we can process normally return(ComparisonHelper.ComparisonExpression(comparisonType.Value, propertyExpression, AttributeConstantExpression(compareToValue))); } else { // No comparison value was specified, so we can filter if the Comparison Type using no value still makes sense if ((ComparisonType.IsBlank | ComparisonType.IsNotBlank).HasFlag(comparisonType)) { // Just checking if IsBlank or IsNotBlank, so let ComparisonExpression do its thing return(ComparisonHelper.ComparisonExpression(comparisonType.Value, propertyExpression, AttributeConstantExpression(string.Empty))); } else if (this.FilterComparisonType.HasFlag(ComparisonType.IsBlank)) { // if this Filter supports IsBlank/IsNotBlank, we can convert this to IsBlank/IsNotBlank if no value was specified if (comparisonType == ComparisonType.EqualTo) { // an EqualTo was specified, but no value was specified, so convert it to a IsBlank return(ComparisonHelper.ComparisonExpression(ComparisonType.IsBlank, propertyExpression, AttributeConstantExpression(string.Empty))); } else if (comparisonType == ComparisonType.NotEqualTo) { // a NotEqualTo was specified, but no value was specified, so convert it to a IsNotBlank return(ComparisonHelper.ComparisonExpression(ComparisonType.IsNotBlank, propertyExpression, AttributeConstantExpression(string.Empty))); } } } } else { // No comparison type specified, so return NoAttributeFilterExpression ( which means don't filter ) return(new NoAttributeFilterExpression()); } } // return NoAttributeFilterExpression ( which means don't filter ) if there isn't enough information to make a Comparison Expression return(new NoAttributeFilterExpression()); }
/// <summary> /// Determines whether the filter's comparison type and filter compare value(s) evaluates to true for the specified value /// </summary> /// <param name="filterValues">The filter values.</param> /// <param name="value">The value.</param> /// <returns> /// <c>true</c> if [is compared to value] [the specified filter values]; otherwise, <c>false</c>. /// </returns> public override bool IsComparedToValue(List <string> filterValues, string value) { if (filterValues == null || filterValues.Count < 2) { return(false); } ComparisonType?filterComparisonType = filterValues[0].ConvertToEnumOrNull <ComparisonType>(); ComparisonType?equalToCompareValue = GetEqualToCompareValue().ConvertToEnumOrNull <ComparisonType>(); var filterValueAsDecimal = filterValues[1].AsDecimalOrNull(); var valueAsDecimal = value.AsDecimalOrNull(); return(ComparisonHelper.CompareNumericValues(filterComparisonType.Value, valueAsDecimal, filterValueAsDecimal, null)); }
public ActionResult StepOne(int companyNo, string matName, ComparisonType?comparisonType) { switch (comparisonType) { case ComparisonType.Advanced: return(Redirect($"/TrustComparison/Advanced?companyNo={companyNo}")); case ComparisonType.Manual: return(Redirect($"/TrustComparison/Manual?companyNo={companyNo}")); default: var model = new TrustViewModel(companyNo, matName); model.ErrorMessage = ErrorMessages.SelectComparisonType; return(View("SelectType", model)); } }
private string GetParameterNameWithEquality(ComparisonType?comparisonType, string parameterName) { if (comparisonType.HasValue) { switch (comparisonType) { case ComparisonType.GreaterThanOrEqualTo: parameterName += ">"; break; case ComparisonType.LessThanOrEqualTo: parameterName += "<"; break; } } return(parameterName); }
/// <summary> /// Determines whether the filter is an 'Equal To' comparison and the filtered value is equal to the specified value. /// </summary> /// <param name="filterValues">The filter values.</param> /// <param name="value">The value.</param> /// <returns> /// <c>true</c> if [is equal to value] [the specified filter values]; otherwise, <c>false</c>. /// </returns> public virtual bool IsEqualToValue(List <string> filterValues, string value) { if (filterValues == null || filterValues.Count != 2) { return(false); } ComparisonType?filterComparisonType = filterValues[0].ConvertToEnumOrNull <ComparisonType>(); ComparisonType?equalToCompareValue = GetEqualToCompareValue().ConvertToEnumOrNull <ComparisonType>(); if (filterComparisonType != equalToCompareValue) { return(false); } return(filterValues[1] == value); }
/// <summary> /// Geta a filter expression for an attribute value. /// </summary> /// <param name="configurationValues">The configuration values.</param> /// <param name="filterValues">The filter values.</param> /// <param name="parameterExpression">The parameter expression.</param> /// <returns></returns> public override Expression AttributeFilterExpression(Dictionary <string, ConfigurationValue> configurationValues, List <string> filterValues, ParameterExpression parameterExpression) { if (filterValues.Count < 2) { return(null); } // Get Comparison Type or exit if none specified. string comparisonTypeValue = filterValues[0]; if (comparisonTypeValue == "0") { return(null); } ComparisonType?comparisonType = comparisonTypeValue.ConvertToEnumOrNull <ComparisonType>(); // If no comparison has been specified, we cannot form a valid filter expression. if (!comparisonType.HasValue) { return(null); } // Get Comparison Date. If a date is required but not specified, we cannot form a valid filter expression. string dateValue = filterValues[1]; if (string.IsNullOrWhiteSpace(dateValue) && comparisonType != ComparisonType.IsBlank && comparisonType != ComparisonType.IsNotBlank) { return(null); } filterValues[1] = ParseRelativeValue(filterValues[1]); DateTime date = filterValues[1].AsDateTime() ?? DateTime.MinValue; MemberExpression propertyExpression = Expression.Property(parameterExpression, "ValueAsDateTime"); ConstantExpression constantExpression = Expression.Constant(date, typeof(DateTime)); return(ComparisonHelper.ComparisonExpression(comparisonType.Value, propertyExpression, constantExpression)); }
/// <summary> /// Gets the filter value. /// </summary> /// <param name="filterControl">The filter control.</param> /// <param name="configurationValues">The configuration values.</param> /// <param name="filterMode">The filter mode.</param> /// <returns></returns> public virtual List<string> GetFilterValues( Control filterControl, Dictionary<string, ConfigurationValue> configurationValues, FilterMode filterMode ) { var values = new List<string>(); if ( filterControl != null ) { try { string compare = GetFilterCompareValue( filterControl.Controls[0].Controls[0], filterMode ); if ( compare != null ) { values.Add( compare ); } ComparisonType? comparisonType = compare.ConvertToEnumOrNull<ComparisonType>(); if ( comparisonType.HasValue && ( ComparisonType.IsBlank | ComparisonType.IsNotBlank ).HasFlag( comparisonType.Value ) ) { // if using IsBlank or IsNotBlank, we don't care about the value, so don't try to grab it from the UI values.Add( string.Empty ); } else { string value = GetFilterValueValue( filterControl.Controls[1].Controls[0], configurationValues ); if ( value != null ) { values.Add( value ); } } } catch { // intentionally ignore error } } return values; }
public async Task <ActionResult> StepOne(long?urn, long?fuid, ComparisonType?comparisonType, bool similarPupils = false) { switch (comparisonType) { case ComparisonType.BestInClass: return(HighestProgressSchoolsBenchmarking(urn.Value)); case ComparisonType.Manual: if (urn.HasValue) { return(RedirectToAction("Index", "ManualComparison")); } else { return(RedirectToAction("WithoutBaseSchool", "ManualComparison")); } case ComparisonType.Basic: case ComparisonType.FederationBasic: case ComparisonType.Advanced: return(await SelectSchoolType(urn, fuid, comparisonType.Value, null, null)); case ComparisonType.Specials: return(await HowWeCalculateSpecials(urn.GetValueOrDefault(), similarPupils)); case null: default: if (urn.HasValue) { return(await ErrorViewForComparisonStrategy(urn.Value)); } else { return(ErrorViewForHomePage(SearchTypes.COMPARE_WITHOUT_DEFAULT_SCHOOL, ErrorMessages.SelectComparisonType, _benchmarkBasketService.GetSchoolBenchmarkList())); } } }
public async Task <ActionResult> GenerateListFromAdvancedCriteria(BenchmarkCriteriaVM criteria, ComparisonType?comparison = null) { if (!ModelState.IsValid) { new TelemetryClient().TrackException(new ApplicationException("Invalid criteria entered for advanced search!" + criteria)); throw new ApplicationException(); } if (criteria.AdvancedCriteria != null && !criteria.AdvancedCriteria.IsAllPropertiesNull()) { _trustBenchmarkListService.ClearTrustBenchmarkList(); _trustBenchmarkListService.AddDefaultTrustToBenchmarkList(); var trustDocs = await _financialDataService.SearchTrustsByCriteriaAsync(criteria.AdvancedCriteria); foreach (var doc in trustDocs) { _trustBenchmarkListService.TryAddTrustToBenchmarkList(doc.CompanyNumber.GetValueOrDefault(), doc.TrustOrCompanyName); } } TempData["BenchmarkCriteria"] = criteria.AdvancedCriteria; TempData["ComparisonType"] = comparison; return(Redirect("/BenchmarkCharts/Mats")); }
/// <summary> /// Builds an expression for an attribute field /// </summary> /// <param name="serviceInstance">The service instance.</param> /// <param name="parameterExpression">The parameter expression.</param> /// <param name="entityField">The entity field.</param> /// <param name="values">The filter parameter values: FieldName, <see cref="ComparisonType">Comparison Type</see>, (optional) Comparison Value(s)</param> /// <returns></returns> public static Expression GetAttributeExpression(IService serviceInstance, ParameterExpression parameterExpression, EntityField entityField, List <string> values) { if (!values.Any()) { // if no filter parameter values where specified, don't filter return(new NoAttributeFilterExpression()); } var service = new AttributeValueService(( RockContext )serviceInstance.Context); var attributeValues = service.Queryable().Where(v => v.EntityId.HasValue); AttributeCache attributeCache = null; if (entityField.AttributeGuid.HasValue) { attributeCache = AttributeCache.Get(entityField.AttributeGuid.Value); var attributeId = attributeCache != null ? attributeCache.Id : 0; attributeValues = attributeValues.Where(v => v.AttributeId == attributeId); } else { attributeValues = attributeValues.Where(v => v.Attribute.Key == entityField.Name && v.Attribute.FieldTypeId == entityField.FieldType.Id); } ParameterExpression attributeValueParameterExpression = Expression.Parameter(typeof(AttributeValue), "v"); // Determine the appropriate comparison type to use for this Expression. // Attribute Value records only exist for Entities that have a value specified for the Attribute. // Therefore, if the specified comparison works by excluding certain values we must invert our filter logic: // first we find the Attribute Values that match those values and then we exclude the associated Entities from the result set. ComparisonType?comparisonType = ComparisonType.EqualTo; ComparisonType?evaluatedComparisonType = comparisonType; // If Values.Count >= 2, then Values[0] is ComparisonType, and Values[1] is a CompareToValue. Otherwise, Values[0] is a CompareToValue (for example, a SingleSelect attribute) if (values.Count >= 2) { comparisonType = values[0].ConvertToEnumOrNull <ComparisonType>(); switch (comparisonType) { case ComparisonType.DoesNotContain: evaluatedComparisonType = ComparisonType.Contains; break; case ComparisonType.IsBlank: evaluatedComparisonType = ComparisonType.IsNotBlank; break; case ComparisonType.LessThan: evaluatedComparisonType = ComparisonType.GreaterThanOrEqualTo; break; case ComparisonType.LessThanOrEqualTo: evaluatedComparisonType = ComparisonType.GreaterThan; break; case ComparisonType.NotEqualTo: evaluatedComparisonType = ComparisonType.EqualTo; break; default: evaluatedComparisonType = comparisonType; break; } values[0] = evaluatedComparisonType.ToString(); } var filterExpression = entityField.FieldType.Field.AttributeFilterExpression(entityField.FieldConfig, values, attributeValueParameterExpression); if (filterExpression != null) { if (filterExpression is NoAttributeFilterExpression) { // Special Case: If AttributeFilterExpression returns NoAttributeFilterExpression, just return the NoAttributeFilterExpression. // For example, If this is a CampusFieldType and they didn't pick any campus, we don't want to do any filtering for this datafilter. return(filterExpression); } else { attributeValues = attributeValues.Where(attributeValueParameterExpression, filterExpression, null); } } else { // AttributeFilterExpression returned NULL ( the FieldType didn't specify any additional filter on AttributeValue), // ideally the FieldType should have returned a NoAttributeFilterExpression, but just in case, don't filter System.Diagnostics.Debug.WriteLine($"Unexpected NULL result from FieldType.Field.AttributeFilterExpression for { entityField.FieldType }"); return(new NoAttributeFilterExpression()); } IQueryable <int> ids = attributeValues.Select(v => v.EntityId.Value); MemberExpression propertyExpression = Expression.Property(parameterExpression, "Id"); ConstantExpression idsExpression = Expression.Constant(ids.AsQueryable(), typeof(IQueryable <int>)); Expression expression = Expression.Call(typeof(Queryable), "Contains", new Type[] { typeof(int) }, idsExpression, propertyExpression); if (attributeCache != null) { // Test the default value against the expression filter. If it pass, then we can include all the attribute values with no value. var comparedToDefault = IsComparedToValue(attributeValueParameterExpression, filterExpression, attributeCache.DefaultValue); if (comparedToDefault) { var allAttributeValueIds = service.Queryable().Where(v => v.Attribute.Id == attributeCache.Id && v.EntityId.HasValue && !string.IsNullOrEmpty(v.Value)).Select(a => a.EntityId.Value); ConstantExpression allIdsExpression = Expression.Constant(allAttributeValueIds.AsQueryable(), typeof(IQueryable <int>)); Expression notContainsExpression = Expression.Not(Expression.Call(typeof(Queryable), "Contains", new Type[] { typeof(int) }, allIdsExpression, propertyExpression)); expression = Expression.Or(expression, notContainsExpression); } // If there is an EntityTypeQualifierColumn/Value on this attribute, also narrow down the entity query to the ones with matching QualifierColumn/Value if (attributeCache.EntityTypeQualifierColumn.IsNotNullOrWhiteSpace() && attributeCache.EntityTypeQualifierValue.IsNotNullOrWhiteSpace()) { Expression qualifierParameterExpression = null; PropertyInfo qualifierColumnProperty = parameterExpression.Type.GetProperty(attributeCache.EntityTypeQualifierColumn); // make sure the QualifierColumn is an actual mapped property on the Entity if (qualifierColumnProperty != null && qualifierColumnProperty.GetCustomAttribute <NotMappedAttribute>() == null) { qualifierParameterExpression = parameterExpression; } else { if (attributeCache.EntityTypeQualifierColumn == "GroupTypeId" && parameterExpression.Type == typeof(Rock.Model.GroupMember)) { // Special Case for GroupMember with Qualifier of 'GroupTypeId' (which is really Group.GroupTypeId) qualifierParameterExpression = Expression.Property(parameterExpression, "Group"); } else if (attributeCache.EntityTypeQualifierColumn == "RegistrationTemplateId" && parameterExpression.Type == typeof(Rock.Model.RegistrationRegistrant)) { // Special Case for RegistrationRegistrant with Qualifier of 'RegistrationTemplateId' (which is really Registration.RegistrationInstance.RegistrationTemplateId) qualifierParameterExpression = Expression.Property(parameterExpression, "Registration"); qualifierParameterExpression = Expression.Property(qualifierParameterExpression, "RegistrationInstance"); } else { // Unable to determine how the EntityTypeQualiferColumn relates to the Entity. Probably will be OK, but spit out a debug message System.Diagnostics.Debug.WriteLine($"Unable to determine how the EntityTypeQualiferColumn {attributeCache.EntityTypeQualifierColumn} relates to entity {parameterExpression.Type} on attribute {attributeCache.Name}:{attributeCache.Guid}"); } } if (qualifierParameterExpression != null) { // if we figured out the EntityQualifierColumn/Value expression, apply it // This would effectively add something like 'WHERE [GroupTypeId] = 10' to the WHERE clause MemberExpression entityQualiferColumnExpression = Expression.Property(qualifierParameterExpression, attributeCache.EntityTypeQualifierColumn); object entityTypeQualifierValueAsType = Convert.ChangeType(attributeCache.EntityTypeQualifierValue, entityQualiferColumnExpression.Type); Expression entityQualiferColumnEqualExpression = Expression.Equal(entityQualiferColumnExpression, Expression.Constant(entityTypeQualifierValueAsType, entityQualiferColumnExpression.Type)); expression = Expression.And(entityQualiferColumnEqualExpression, expression); } } } // If we have used an inverted comparison type for the evaluation, invert the Expression so that it excludes the matching Entities. if (comparisonType != evaluatedComparisonType) { return(Expression.Not(expression)); } else { return(expression); } }
/// <summary> /// Builds an expression for an attribute field /// </summary> /// <param name="serviceInstance">The service instance.</param> /// <param name="parameterExpression">The parameter expression.</param> /// <param name="entityField">The entity field.</param> /// <param name="values">The filter parameter values.</param> /// <returns></returns> public static Expression GetAttributeExpression(IService serviceInstance, ParameterExpression parameterExpression, EntityField entityField, List <string> values) { if (!values.Any()) { // if no filter parameter values where specified, don't filter return(new NoAttributeFilterExpression()); } var service = new AttributeValueService(( RockContext )serviceInstance.Context); var attributeValues = service.Queryable().Where(v => v.EntityId.HasValue); AttributeCache attributeCache = null; if (entityField.AttributeGuid.HasValue) { attributeCache = AttributeCache.Get(entityField.AttributeGuid.Value); var attributeId = attributeCache != null ? attributeCache.Id : 0; attributeValues = attributeValues.Where(v => v.AttributeId == attributeId); } else { attributeValues = attributeValues.Where(v => v.Attribute.Key == entityField.Name && v.Attribute.FieldTypeId == entityField.FieldType.Id); } ParameterExpression attributeValueParameterExpression = Expression.Parameter(typeof(AttributeValue), "v"); // Determine the appropriate comparison type to use for this Expression. // Attribute Value records only exist for Entities that have a value specified for the Attribute. // Therefore, if the specified comparison works by excluding certain values we must invert our filter logic: // first we find the Attribute Values that match those values and then we exclude the associated Entities from the result set. ComparisonType?comparisonType = ComparisonType.EqualTo; ComparisonType?evaluatedComparisonType = comparisonType; string compareToValue = null; if (values.Count >= 2) { comparisonType = values[0].ConvertToEnumOrNull <ComparisonType>(); compareToValue = values[1]; switch (comparisonType) { case ComparisonType.DoesNotContain: evaluatedComparisonType = ComparisonType.Contains; break; case ComparisonType.IsBlank: evaluatedComparisonType = ComparisonType.IsNotBlank; break; case ComparisonType.LessThan: evaluatedComparisonType = ComparisonType.GreaterThanOrEqualTo; break; case ComparisonType.LessThanOrEqualTo: evaluatedComparisonType = ComparisonType.GreaterThan; break; case ComparisonType.NotEqualTo: evaluatedComparisonType = ComparisonType.EqualTo; break; default: evaluatedComparisonType = comparisonType; break; } values[0] = evaluatedComparisonType.ToString(); } var filterExpression = entityField.FieldType.Field.AttributeFilterExpression(entityField.FieldConfig, values, attributeValueParameterExpression); if (filterExpression != null) { if (filterExpression is NoAttributeFilterExpression) { // Special Case: If AttributeFilterExpression returns NoAttributeFilterExpression, just return the NoAttributeFilterExpression. // For example, If this is a CampusFieldType and they didn't pick any campus, we don't want to do any filtering for this datafilter. return(filterExpression); } else { attributeValues = attributeValues.Where(attributeValueParameterExpression, filterExpression, null); } } else { // AttributeFilterExpression returned NULL ( the FieldType didn't specify any additional filter on AttributeValue), // ideally the FieldType should have returned a NoAttributeFilterExpression, but just in case, don't filter System.Diagnostics.Debug.WriteLine($"Unexpected NULL result from FieldType.Field.AttributeFilterExpression for { entityField.FieldType }"); return(new NoAttributeFilterExpression()); } IQueryable <int> ids = attributeValues.Select(v => v.EntityId.Value); MemberExpression propertyExpression = Expression.Property(parameterExpression, "Id"); ConstantExpression idsExpression = Expression.Constant(ids.AsQueryable(), typeof(IQueryable <int>)); Expression expression = Expression.Call(typeof(Queryable), "Contains", new Type[] { typeof(int) }, idsExpression, propertyExpression); if (attributeCache != null) { var comparedToDefault = entityField.FieldType.Field.IsComparedToValue(values, attributeCache.DefaultValue); if (comparedToDefault) { var allAttributeValueIds = service.Queryable().Where(v => v.Attribute.Id == attributeCache.Id && v.EntityId.HasValue && !string.IsNullOrEmpty(v.Value)).Select(a => a.EntityId.Value); ConstantExpression allIdsExpression = Expression.Constant(allAttributeValueIds.AsQueryable(), typeof(IQueryable <int>)); Expression notContainsExpression = Expression.Not(Expression.Call(typeof(Queryable), "Contains", new Type[] { typeof(int) }, allIdsExpression, propertyExpression)); expression = Expression.Or(expression, notContainsExpression); } } // If we have used an inverted comparison type for the evaluation, invert the Expression so that it excludes the matching Entities. if (comparisonType != evaluatedComparisonType) { return(Expression.Not(expression)); } else { return(expression); } }
/// <summary> /// Set the property values parsed from a settings string. /// </summary> /// <param name="version">The version number of the parameter set.</param> /// <param name="parameters">An ordered collection of strings representing the parameter values.</param> protected override void OnSetParameters( int version, IReadOnlyList<string> parameters ) { // Parameter 1: Group Member Data View GroupMemberDataViewGuid = DataComponentSettingsHelper.GetParameterOrEmpty( parameters, 0 ).AsGuidOrNull(); // Parameter 2: Group Member Count Comparison Type MemberCountComparison = DataComponentSettingsHelper.GetParameterAsEnum( parameters, 1, ComparisonType.GreaterThan ); // Parameter 3: Group Member Count MemberCount = DataComponentSettingsHelper.GetParameterOrEmpty( parameters, 2 ).AsIntegerOrNull(); }