Feature Request: More options for dealing with DataSourceResults

4 posts, 0 answers
  1. Robert
    Robert avatar
    38 posts
    Member since:
    Feb 2012

    Posted 27 Jun 2012 Link to this post

    Scenario:

    I have objects in the database I want to bind to a Grid. But those objects need to be converted into Models in order to avoid circular references in serialization, or to be able to have one of your Model properties equal a string representation of a child object.

    A typical method of accomplishing this transformation using the Entity Framework is to materialize the query to a list, and then call materializedList.Select(c => c.ToModel()).

    The problem is, it is not readily apparent how this is possible with the DataSourceRequest and DataSourceResult, because DataSourceResult.Data is not generic. And I know there is an example controller called CustomServerBinding that demonstrates this scenario, but it looks ridiculously complicated to implement for most scenarios.

    I see two possibilities to handle this scenario:
    • Create an extension to IQueryable called ApplyGridParameters(DataSourceRequest) that would accomplish everything in ToDataSourceResult() EXCEPT for returning the DataSourceResult. Then, add an extension method for IEnumerable called ToDataSourceResult() that does not take a DataSourceRequest object. That version of the method would already assume the filters have been applied, and just load up the DataSourceResult properly.
    This would allow me to write code like:
    var transformedList = dbResults.ApplyGridParameters(kendoRequest).ToList().Select(c => c.ToModel());
    return Json(transformedList.ToDataSourceResult());

    • Create an overload to IQueryable.ToDataSourceResult(DataSourceRequest) that allows me to pass in a Func to apply to the data after the query is materialized, but before it is set to the DataSourceResult.Data property. This option would be the most flexible, because you could literally do anything with it.
    This would allow me to write code like:
    return Json(dbResults.ToDataSourceResult(request, c => c.ToModel());

    or even something like this:
    var results = dbResults.ToDataSourceResult(request, c => { DoSomething(c); DoSomethingElse(c); });
    return Json(results);

    Obviously, this method looks a lot cleaner.

    For now, I'm left with getting everything from the database, and filtering it after the fact. One of these options would allow me to pass the query back with minimal effort, and transform only the data I'm actually going to use.

    Thanks!
  2. Atanas Korchev
    Admin
    Atanas Korchev avatar
    8462 posts

    Posted 02 Jul 2012 Link to this post

    Hello Robert,

     Creating such an extension method is possible but won't solve that problem completely. The Kendo Grid needs the "total" number of records which is calculated *after* applying filtering. This information will be lost if we just return an IQueryable from a hypothetical ApplyGridParameters method.

     On a side note why can't you do the following:

    materializedList.Select(c => c.ToModel()).ToDataSourceResult():

     The projection would not cause retrieving of all data from the data base.

    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!
  3. UI for ASP.NET MVC is VS 2017 Ready
  4. Robert
    Robert avatar
    38 posts
    Member since:
    Feb 2012

    Posted 02 Jul 2012 Link to this post

    Regarding your side note, you can't do that if the ToModel() function itself calls a function, because that can't be translated to a database query. So you would have to materialize the query first, hence why I called my pseudolist "materialized list". You have to get the results back from the database before you can translate them in this fashion, which is why I would need to be able to apply the Grid Parameters to the source data before calling ToList().

    Regarding the first part of your post, I'm not sure why that is a problem, because ApplyGridParameters would apply the additional LINQ filters to the data, which would allow me to call sourceQuery.ApplyGridParameters().ToList().Select(c => c.ToModel()).ToDataSourceResult(), which would pass in a list that you could call Count() on to get the total number of results.
  5. Atanas Korchev
    Admin
    Atanas Korchev avatar
    8462 posts

    Posted 02 Jul 2012 Link to this post

    Hi Robert,

     There is a detailed discussion about this very topic here: http://www.kendoui.com/forums/mvc/general-discussions/filterdescriptor-cs-ifilterdescriptor-can-we-see-what-it-looks-like.aspx 

     The main reason why such an extension method cannot be supported is grouping and aggregates. When those are involved the result is no longer IQueryable<T>. 

    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!
Back to Top
UI for ASP.NET MVC is VS 2017 Ready