telerik mvc 创建 CompositeFilterDescriptor 并将其附加到现有数据源请求过滤器

telerik mvc Create CompositeFilterDescriptor and append it to existing datasource request filter

我在从头开始创建 CompositeFilterDescriptor 时遇到一些问题。

场景:我们在网格上有日期过滤器,但显示的是日期时间字段。

当 Someone 过滤到特定日期时,我们会显示当天的所有记录。

当某人过滤的日期大于该天时,我们会编辑该过滤器的 filterDescriptor 并向其添加一天。

当有人过滤到小于或等于那一天时,我们编辑该过滤器的过滤器描述符并向其添加一天。

问题在于:当有人选择“不等于”时,解决方案是创建一个包含两个过滤器的 compositeFilterDescriptor。小于那一天一张,大于那一天一张

我可能没有正确完成这部分。我不知道如何将新的 compositeFilterDescriptor 添加到现有的 dataSourceRequest。

这是我的:

static public DataSourceRequest FixDateFilters(DataSourceRequest request, string[] optionalFields = null)
    {
        if (request?.Filters != null)
        {
            List<string> matchingFields = new List<string> { "utc", "time" };
            List<FilterDescriptor> newDescriptors = new List<FilterDescriptor>();

            //if any fields specific to a page have been passed in, append them to the list.
            if (optionalFields != null)
            {
                foreach (string field in optionalFields)
                    matchingFields.Append(field);
            }

            foreach (string matchingField in matchingFields)
            {
                List<FilterDescriptor> descriptors = new List<FilterDescriptor>();
                FilterDescriptor descriptor1 = FindFirstFilterByMember(request.Filters, matchingField, true, null);
                //there could be up to two filters on a matching field.  Get the 2nd one if it exists.
                FilterDescriptor descriptor2 = FindFirstFilterByMember(request.Filters, matchingField, true, descriptor1);

                //turn the matches into a list for iterating
                if (descriptor1 != null)
                    descriptors.Add(descriptor1);
                if (descriptor2 != null)
                    descriptors.Add(descriptor2);
                if (descriptors.Count != 0)
                {
                    foreach (FilterDescriptor descriptor in descriptors)
                    {
                        DateTime? utcDate = (DateTime?)descriptor?.Value;
                        if (utcDate.HasValue)
                        {
                            utcDate = Core.DateHelper.ToUTC(utcDate.Value, HttpContext.Current); //make sure date ranges are one day ranges in local time
                        }

                        if (utcDate != null)
                        {
                            if (descriptor.Operator == FilterOperator.IsLessThanOrEqualTo)
                            {
                                utcDate = ((DateTime)utcDate).AddDays(1);
                                descriptor.Value = utcDate;
                            }
                            else if (descriptor.Operator == FilterOperator.IsGreaterThan)
                            {
                                utcDate = utcDate.Value.AddDays(1);
                                descriptor.Value = utcDate;
                            }
                            else if (descriptor.Operator == FilterOperator.IsEqualTo)
                            {
                                descriptor.Operator = FilterOperator.IsGreaterThanOrEqualTo;
                                newDescriptors.Add(new FilterDescriptor(descriptor.Member, FilterOperator.IsLessThan, utcDate.Value.AddDays(1)));
                            }
                            else if (descriptor.Operator == FilterOperator.IsNotEqualTo)
                            {
                                CompositeFilterDescriptor cfd = new CompositeFilterDescriptor();
                                cfd.LogicalOperator = FilterCompositionLogicalOperator.Or;
                                cfd.FilterDescriptors.Add(new FilterDescriptor(descriptor.Member, FilterOperator.IsLessThan, utcDate.Value;));
                                cfd.FilterDescriptors.Add(new FilterDescriptor(descriptor.Member, FilterOperator.IsGreaterThan, utcDate.Value.AddDays(1)));
                                newDescriptors.Add( cfd);
                            }
                        }
                    }
                }
            }
            //equals matches add a new descriptor so add them after the foreach is done so they don't affect the foreach.
            foreach (FilterDescriptor newDescriptor in newDescriptors)
            {
                if (newDescriptor.Member != "") //a blank descriptor has a emptry string for member
                {
                    request.Filters.Add(newDescriptor);
                }
            }
        }
        return request;
    }

}

    static public FilterDescriptor FindFirstFilterByMember(IEnumerable<IFilterDescriptor> filters, string findMember, bool partialMatch = false, FilterDescriptor previous = null)
    {
        FilterDescriptor ret = null;
        foreach (var filter in filters)
        {
            var descriptor = filter as FilterDescriptor;
            if (descriptor != null 
                && (descriptor.Member == findMember || (partialMatch == true && descriptor.Member.ToLower().Contains(findMember.ToLower()))) 
                && (previous == null || previous != descriptor))
            {
                ret = descriptor;
                break;
            }
            else if (filter is CompositeFilterDescriptor)
            {
                ret = FindFirstFilterByMember(((CompositeFilterDescriptor)filter).FilterDescriptors, findMember, partialMatch, previous);
                if (ret != null)
                    break;
            }
        }
        return ret;
    }

第二个函数是递归函数,用于按字符串获取过滤器。

问题部分是“isNotEqualTo”比较。我不知道如何将复合过滤器保存到现有请求中。它给了我一个转换错误。

好的,事实证明我需要做的就是创建一个新的 CompositeFilterDescriptor 类型列表并在必要时附加它。 .add 函数同时采用了两者。叹息

            foreach (CompositeFilterDescriptor newCompositeDescriptor in newCompositeDescriptors)
            {
                request.Filters.Add(newCompositeDescriptor);
            }