FilterDescriptor.cs (IFilterDescriptor) can we see what it looks like?

Thread is closed for posting
22 posts, 0 answers
  1. Vesselin Obreshkov
    Vesselin Obreshkov avatar
    81 posts
    Member since:
    Jan 2010

    Posted 26 Jun 2012 Link to this post

    Trying to make our sorting and filtering working with what comes in a DataSourceRequest but since the source codes for Kendo.Mvc.dll aren't available (yet?), can we see what your FilterDescriptor looks like (I can only see an IFilterDescriptor interface which has one method by going to object definitions).

    I can submit a support ticket if that's a preferred way.

    Thanks
  2. Atanas Korchev
    Admin
    Atanas Korchev avatar
    8462 posts

    Posted 27 Jun 2012 Link to this post

    Hello Vesselin,

     The FilterDescriptor is a public class which is available in the Kendo.Mvc namespace. It is basically the same as in Telerik Extensions for ASP.NET MVC. I have attached this file for your convenience.

     On a side note the source code will be available with the official release.

    All the best,
    Atanas Korchev
    the Telerik team
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  3. UI for ASP.NET MVC is VS 2017 Ready
  4. Victor
    Victor avatar
    167 posts
    Member since:
    Nov 2010

    Posted 27 Jun 2012 Link to this post

    Very nice, thank you!

    We had a similair question before - may I suggest that you expose the internal sorting and filtering function as public? That is - to use it the filtering and sortering right now we concluder (correctly?) that you have to call ToDataSourceResult() and use the result. It would however be nice if the sort/filter/etc functionality is exposed as well.

    Otherwise, very clean solution (returing Json(....ToDataSourceRequest()) etc) compared to the [GridAttribute] solution in Telrik ASP MVC. Very nice and transparent!

    Thanks!
    /Victor
  5. Atanas Korchev
    Admin
    Atanas Korchev avatar
    8462 posts

    Posted 28 Jun 2012 Link to this post

    Hello Victor,

     Those are already exposed as IQyeryable extension methods: Page, Sort, GroupBy etc.

    All the best,
    Atanas Korchev
    the Telerik team
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  6. Victor
    Victor avatar
    167 posts
    Member since:
    Nov 2010

    Posted 28 Jun 2012 Link to this post

    Hi and thanks for your reply!

    We know that those functions are exposed, however it would be nice if the function calling all the separate functions (sort, filter, etc) was exposed as well. Preferably taking in IQueryable<T> and returning IQuearyable<T> if possible.

    Edit: Since we feel we might miss something if we use the individual functions we right now use the ToDataSourceResult() with some casting to get it back to the original type. We do this in the server side function generating the grid to get the same behaviour as for the functions returning the Json results for paging/sorting/etc.


    /Victor
  7. Atanas Korchev
    Admin
    Atanas Korchev avatar
    8462 posts

    Posted 28 Jun 2012 Link to this post

    Hi Victor,

     We don't have such a function because we need the Total count of records as well. It would be lost if we process all data in a single method.

    All the best,
    Atanas Korchev
    the Telerik team
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  8. Victor
    Victor avatar
    167 posts
    Member since:
    Nov 2010

    Posted 28 Jun 2012 Link to this post

    Hi,
    We realize that, and we realize that it would not (and should not) replace the ToDataSourceResult() function, it would still be convenient to have the sort/filter/etc functionality exposed in a single function. We could then do something like:

    var viewModel = new CustomViewModel();
    var unfilteredList = GetCustomViewModelList();
    viewModel.TotalRows = unfilteredList.Count();
    viewModel.Records = unfiltereredList.ApplyRequestFiltering(request);
    return View(viewModel);

    and refactor most of this code to be common between server side and ajax request functions. One reason we want this is since we often have som post-processing that shoud be done after sorting and filtering has been done to add some custom, complex properties in memory, similair to:

    var viewModel = new CustomViewModel();
    var unfilteredList = GetCustomViewModelList();
    viewModel.TotalRows = unfilteredList.Count();
    viewModel.Records = unfiltereredList.ApplyRequestFiltering(request).ToList(); //actual EF query to result in memory
    viewModel.Records.ForEach(record => record.CustomProperty = String.Join(",", record.CustomListProperty));
    return View(viewModel);

    Right now this is possible via Cast<CustomViewModel> after calling ToDataSourceResult(), unfortunately this creates quite cumbersome code. So optimally we would like the option to do something like:

    //Code as before but refactored
    return View(alreadyFilteredAndSortedViewModel.AddCustomCalculatedProperties().ToDataSourceResult(totalCount));

    Hope this clarifies our objectives. Of course the implementation could be different, but the goal would for us be:
    • Possibility to refactor out creation, filtering and sorting to a method to be used for both server-side and ajax requests
    • Possibility to use non-db functions on the resulting, filtered, request (such as String.Join()), thus applied on 20 results rather than on 20000.
    /Victor
  9. Atanas Korchev
    Admin
    Atanas Korchev avatar
    8462 posts

    Posted 28 Jun 2012 Link to this post

    Hello Victor,

     I will add this for to our TODO list. Hopefully it would make it in the final release.

    Greetings,
    Atanas Korchev
    the Telerik team
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  10. Victor
    Victor avatar
    167 posts
    Member since:
    Nov 2010

    Posted 28 Jun 2012 Link to this post

    Perfect, thanks a lot.

    /Victor
  11. Atanas Korchev
    Admin
    Atanas Korchev avatar
    8462 posts

    Posted 02 Jul 2012 Link to this post

    Hello Victor,

     While researching the implementation of such extension methods I found to obstacles. The ToDataSourceResult extension method supports aggregates and grouping. However the result from those two operations is no longer IQueryable<T>. This means that an extension method which takes IQueryable<T> and returns IQueryable<T> will not support aggregates and grouping. In this case I don't think such a method would have any value.

     Right now we can either expose a method called ProcessDataSourceRequest which will not support (and never support) grouping and aggregates or just skip that method altogether. What do you think?

    Regards,
    Atanas Korchev
    the Telerik team
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  12. Victor
    Victor avatar
    167 posts
    Member since:
    Nov 2010

    Posted 02 Jul 2012 Link to this post

    Hi again and thanks for getting back to me.

    A more complete example of what we are trying to accomplish can be found in this other thred: http://www.kendoui.com/forums/mvc/grid/grid-reorders-server-side-data-even-when-no-sort-order-is-specified.aspx#2170196

    Basically the part feels very cumbersome, but that was the best we could come up with for now:
    var result = producers
                    .Take(request.PageSize)
                    .ToList()
                    .ToDataSourceResult(request);
    var producersList = result.Data.Cast<ProducerViewModel>().ToList();

    Hopefully this clarifies some, otherwise, please get back to us!

    /Victor
  13. Atanas Korchev
    Admin
    Atanas Korchev avatar
    8462 posts

    Posted 02 Jul 2012 Link to this post

    Hi Victor,

    Your code will also fail if grouping or aggregates are enabled. The following cast will fail: 

    result.Data.Cast<
    ProducerViewModel>().ToList(); 

    So the question I am asking is how grouping and aggregates should be handled in this case - an exception should be thrown or what?

    Regards,
    Atanas Korchev
    the Telerik team
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  14. Victor
    Victor avatar
    167 posts
    Member since:
    Nov 2010

    Posted 02 Jul 2012 Link to this post

    Oh, I see... We actually only tried sorting and filtering, so we didnt realize grouping would not work.

    Anyway, as you can see from the linked thread (previous post), we want to be able to post-process the correct page of results in-memory.

    So - I suppose what we need to do is (have I missed any steps?):
    1. Sort
    2. Skip
    3. Take
    4. ToList (DB => Memory)
    5. Custom post processing (processing that cannot be done on the DB side)
    6. ToDataSourceResult

    Also in (6) we would need to provide some inputs from (1)-(3), such as total count and current page number.

    /Victor

  15. Atanas Korchev
    Admin
    Atanas Korchev avatar
    8462 posts

    Posted 02 Jul 2012 Link to this post

    Hi Victor,

     This seems about right. You can reset the paging and sorting info to avoid double paging and sorting:

    request.Page = 0;
    request.PageSize = 0;

    result = data.Skip().Take().OrderBy().ToList().ToDataSourceResult(request);

    Regards,

    Atanas Korchev
    the Telerik team
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  16. Victor
    Victor avatar
    167 posts
    Member since:
    Nov 2010

    Posted 03 Jul 2012 Link to this post

    Hi,
    Thanks for that! However I am not sure how to do this correctly currently. 1-5 is not Kendo related and will be done "as usual" (with changes to work with datasourcerequest of course), however 6 I am not sure about...

    How do I return a datasource-result correctly? That is - before (1) i take out the full IQueryable the count, I do 1-5. I then have a list of say 25 sorted items (from page 10, out of 1000) and want to return the correct datasourceresponse supporting aggregates and filters.

    /Victor


  17. Atanas Korchev
    Admin
    Atanas Korchev avatar
    8462 posts

    Posted 03 Jul 2012 Link to this post

    Hello Victor,

     I am starting to think that this problem should be solved in a different manner. If the only thing you want is to do some sort of projection over the process data we can probably think find another solution. How about something like this?

    var result = data.ToDataSourceResult(request, (db) => toMemory(db)) 

    The extension method would take the selector and use it internally to do the required projections. Do you think this would work?

    Regards,

    Atanas Korchev
    the Telerik team
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  18. Victor
    Victor avatar
    167 posts
    Member since:
    Nov 2010

    Posted 03 Jul 2012 Link to this post

    Hmm...

    Sounds like a very tempting solution! I am not sure exactly how you think about implementing it, but for us we need to be able to provide a custom projection. Usually we use Automapper  for our projections and will need for custom aggregate functions not supported in the DB, such as String.Join() in the simplest case. Automapper is of course not a requirement, but the syntax is very appealing:
    IEnumerable<OrderViewModel> dto = Mapper.Map<IEnumerable<Order>, IEnumerable<OrderDto>>(ordersFromDb);

    If I understand you correctly we would do something like one of these two:
    (1)
    var db = companiesSet.Where(...);
    var result = data.ToDataSourceResult(request, (db) => toMemory(db));
     
    ...
    function CompanyViewModel toMemory(Company dbCompany) {
    return  Mapper.Map<Company, CompanyViewModel>(dbCompany);
       //Or non Automapper projection
    }


    (2)
    var db = companiesSet.Where(...).Select(c => new CompanyViewModel(...));
    var result = data.ToDataSourceResult(request, (db) => inMemoryPostProcessing(db));
     
    ...
    function CompanyViewModel inMemoryPostProcessing(CompanyViewModel companyViewModel) {
        //Custom in memory code such as sting join
    }


    Is that what you suggest?
    /Victor
  19. Atanas Korchev
    Admin
    Atanas Korchev avatar
    8462 posts

    Posted 03 Jul 2012 Link to this post

    Hello Victor,

     Yes, #1 is the way I was thinking it could work. The implementation won't be easy but is still doable and would work in all cases (even when grouping and aggregates are involved).

    Regards,
    Atanas Korchev
    the Telerik team
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  20. Victor
    Victor avatar
    167 posts
    Member since:
    Nov 2010

    Posted 03 Jul 2012 Link to this post

    #1 seems like a very good solution, and as you say a general one that will work well.

    /Victor
  21. Atanas Korchev
    Admin
    Atanas Korchev avatar
    8462 posts

    Posted 03 Jul 2012 Link to this post

    Hi Victor,

     I've just implemented that overload. The feature would be available in the official release.

    All the best,
    Atanas Korchev
    the Telerik team
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  22. Victor
    Victor avatar
    167 posts
    Member since:
    Nov 2010

    Posted 03 Jul 2012 Link to this post

    Fantastic! That will be very helpful for more advanced mappings!

    /Victor
  23. Mo
    Mo avatar
    14 posts
    Member since:
    Jul 2012

    Posted 20 Jul 2012 Link to this post

    Is this feature is the newest release- 2012.2.710? I have tried to use it in a very similar manner to what was requested, using AutoMapper, and get an exception:

    My code:

    DataSourceResult result = this.StateProvinceService
                    .GetQueryable()
                    .ToDataSourceResult<StateProvince, StateProvinceModel>(
                        request,
                        province => Mapper.Map<StateProvince, StateProvinceModel>(province));

    The result:

    LINQ to Entities does not recognize the method 'XYZ.Web.Areas.Admin.Models.StateProvinceModel Map[StateProvince,StateProvinceModel](XYZ.Model.StateProvince)' method, and this method cannot be translated into a store expression.


    Any advice?
Back to Top
UI for ASP.NET MVC is VS 2017 Ready