Server side filtering and sorting using RadDataFilter with plain WCF services

6 posts, 0 answers
  1. Rajat Panwar
    Rajat Panwar avatar
    11 posts
    Member since:
    Aug 2009

    Posted 30 Nov 2012 Link to this post

    We have a scenario that we have to use RadDataFilter with RadGridView. Now we want to do Sorting and Filtering serverside, But the constraint here is that we have to use only plain WCF Services. No WCF RIA or WCF Data Services.
    So problem is how to send filters to server through string.

    We found a class to convert filter descriptors to dynamiclinq (string format).

    public static class DescriptorsExtensions
        {
            public static string ToDynamicLinq(this SortDescriptorCollection source)
            {
                var result = new List<string>();
     
                foreach (var d in source)
                {
                    if (d is SortDescriptor)
                    {
                        result.Add(((SortDescriptor)d).ToDynamicLinq());
                    }
                    else if (d is ColumnSortDescriptor)
                    {
                        result.Add(((ColumnSortDescriptor)d).ToDynamicLinq());
                    }
                }
                 
                return String.Join(",", result.ToArray());
            }
     
            public static string ToDynamicLinq(this FilterDescriptorCollection source)
            {
                var result = new List<string>();
     
                foreach (var d in source.OfType<IColumnFilterDescriptor>())
                {
                    result.Add(d.ToDynamicLinq());
                }
                 
                return String.Join(" && ", result.ToArray());
            }
     
            public static string ToDynamicLinq(this GroupDescriptorCollection source)
            {
                return String.Join(",", source.OfType<GroupDescriptor>().Select(d => d.Member).ToArray());
            }
     
            public static string ToDynamicLinq(this SortDescriptor source)
            {
                return String.Format("{0} {1}", source.Member,
                    source.SortDirection == System.ComponentModel.ListSortDirection.Ascending ? "asc" : "desc");
            }
     
            public static string ToDynamicLinq(this ColumnSortDescriptor source)
            {
                return String.Format("{0} {1}", source.Column.UniqueName,
                    source.SortDirection == System.ComponentModel.ListSortDirection.Ascending ? "asc" : "desc");
            }
     
     
            public static string ToDynamicLinq(this GroupDescriptor source)
            {
                return String.Format("{0} {1}", source.Member,
                    source.SortDirection == System.ComponentModel.ListSortDirection.Ascending ? "asc" : "desc");
            }
     
            /// <summary>
            /// OLD BROKEN
            /// </summary>
            /// <param name="source"></param>
            /// <returns></returns>
            //public static string ToDynamicLinq(this ColumnFilterDescriptor source)
            //{
            //    var result = new List<string>();
     
            //    foreach (var item in source.DistinctFilter.DistinctValues)
            //    {
            //        result.Add(String.Format("{0} == {1}", source.DistinctFilter.Member, item.GetType() == typeof(string) ?
            //            String.Format(@"""{0}""", item) : item));
            //    }
     
            //    return String.Join(" || ", result.ToArray());
            //}
     
            /// <summary>
            /// NEW
            /// </summary>
            /// <param name="source"></param>
            /// <returns></returns>
            public static string ToDynamicLinq(this IColumnFilterDescriptor source)
            {
                var result = new List<string>();
     
                foreach (var item in source.DistinctFilter.DistinctValues)
                {
                    result.Add(String.Format("{0} == {1}", source.Column.UniqueName, item.GetType() == typeof(string) ?
                        String.Format(@"""{0}""", item) : item));
                }
     
                return String.Join(" || ", result.ToArray());
            }
     
     
        }

    Now the problem with this class is that it always returns string to be empty when we use extension ToDynamicLinq for FilterDescriptors. The commented out method is not compatible with latest release of Silverlight telerik dlls.

    Can you please send us a sample project where we can achieve sorting and filtering on server side with RadDataFilter using only Plain WCF Services.

    The problem I could see was that in foreach loop, the descriptor are not of type IColumnFilterDescriptor (Check attached image)

    rather they are of type Filterdescriptor so extension method taking IColumnFilterDescriptor is not called.

    Please check the attached image for clarification.

    Thanks and Regards,
    Rajat Panwar







  2. Rossen Hristov
    Admin
    Rossen Hristov avatar
    2478 posts

    Posted 30 Nov 2012 Link to this post

    Hi,

    RadDataFilter does not have IColumnFilterDescriptors since it does not have any columns. In fact the IColumnFilterDescriptor interface was created for UI purposes only when you want to filter RadGridView programmatrically. You don't need to be bothering with this interface -- all the filtering information is contained in two main classes -- CompositeFilterDescriptor and FilterDescriptor.

    RadDataFilter.FilterDescriptors collection is a hierarchical tree of CompositeFilterDescriptors (non-leaf nodes) and FilterDescriptors (leaf nodes) which store all the information that you see in RadDataFilter's UI. You can traverse this tree of filter descriptors and build any kind of query string according to your needs.

    You can check this article out. It is filed under RadGridView, but they share the same FilterDescriptor classes with RadDataFilter. There are several diagrams which display how filter descriptors (simple and composite) are combined in a hierarchical tree of filtering criteria.

    So if you want to build a query string based on the RadDataFilter filtering information you would have to traverse the entire tree of filter descriptors. 
     
    FilterDescriptors are plain CLR objects which have properties that are described in the article above.

    The FilterDescriptor (the simple, leaf node) has Member, Operator, Value and IsCaseSensitie.

    The CompositeFilterDescriptor (the composite, non-leaf node) has a LogicalOperator (AND or OR) and a collection of child descriptors called FilterDescriptors which can be in turn both simple or composite. This allows for infinite hierarchies of filtering conditions.

    So your basic task is traversing a tree of CLR objects, reading their properties and builidng any query string that you want. Or building this dynamic linq expression -- it does not matter.

    I hope this helps.

    Greetings,
    Rossen Hristov
    the Telerik team

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

  3. DevCraft banner
  4. Rajat Panwar
    Rajat Panwar avatar
    11 posts
    Member since:
    Aug 2009

    Posted 30 Nov 2012 Link to this post

    Hello,

    Thanks for your quick reply. This has helped me understanding actually how query can be generated from filter descriptors.

    But can you please give me some code that can work as an extension or I can convert filterdescriptors of VirtualQueryableCollectionView
    to a string directly which can be sent to where clause of LinqDataSource on server side.

    Actually I am very short of time with other things for development. So instead of hit and try creating this method on my own, I am asking you guys to send me some code because you are more experts.

    Please help me. and Thanks a lot again for your time and quick response.

    Thanks and Regards,
    Rajat Panwar 
  5. Rajat Panwar
    Rajat Panwar avatar
    11 posts
    Member since:
    Aug 2009

    Posted 05 Dec 2012 Link to this post

    Hello

    Thanks for your reply. I tried doing that and creating a query string out of filterdescriptors. Now the problem is how can I execute the string on server side.
    Lets say I have created this query from filter descriptors

    AccountId IsGreaterThan 100 && AccountName StartsWith "a" && ( (CreatedOn IsLessThan 05-12-2012 00:00:00 ) AND (AccountName Contains "a" ) )

    Now I was using LinqDataSource on server side and thought of passing this string to where clause but unluckily, It throws and exception.

    Can you please guide us how we can execute this query on server side.

    Thanks and Regards,
    Rajat Panwar

  6. Mike
    Mike avatar
    75 posts
    Member since:
    Nov 2011

    Posted 21 Aug 2014 Link to this post

    Hello, 

    Is there any update about this topic? 

    Thanks 
    Regards
  7. Dimitrina
    Admin
    Dimitrina avatar
    3769 posts

    Posted 22 Aug 2014 Link to this post

    Hi,

    You can check the last reply from my colleague. It still applies. 

    Regards,
    Didie
    Telerik
     
    Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
     
Back to Top
DevCraft banner