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:
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());
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!
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!