Overriding Telerik Radgrid data binding - c#

I have a scenario where currently a telerik radgrid (webforms) is used on a page which currently allows telerik to control the paging, sorting, filtering etc. However I have noticed as this uses the default telerik behavior for these tasks it does it all in memory so nothing is lazy loaded.
In this instance there is a situation where upwards of 300,000 rows (1.2 million at one point), are returned and this seems to re-query every time it is paged, sorted etc which is cripplingly slow.
Now I want to push these concerns to the server side, as currently the db interactions happen via linq to sql so I would like to instead of just using the base (300k query) take the composable IQueryable and then add the filtering, sorting and paging logic in from the telerik control, as the data all seems to be there, I just dont know when I should be intercepting the controls data bindings to force it to only get the data it needs.
From my current investigating there is an OnSortCommand method, which seems to be triggered when a sort is requested, so I assume from there I can get the SortExpression and put that into the linq query, then there is also a FilterExpression which I can use to constrain the results in the query, and then finally there is the PageSize and CurrentPageIndex variables which allow me to work out how many pages I should be bringing back.
So all the data needed to constrain the queries exists there, however I dont know when I should be intercepting the binding process as currently if I were to intercept OnDataBinding and override the DataSource to take into account the filterexpression and paging details (as sorting is not available until a sorting command to my knowledge) then I would expect there to be only a query to pull back 50 rows (or whatever the page size is), however it seems to do the 300k query, then afterwards do the 50 row query, so I am confused as to if I should be intercepting another event or method.
If anyone could point me in a direction of what I should be intercepting/overriding I would be VERY grateful, as the documentation provided by telerik for this is not that great.
== Edit ==
Just to be a bit more specific about the scenario, I am not really wanting to internally create the datasource (advanced databinding) as they need to be re-usable components, so the control is created on the aspx page, then in the code behind on page load it will set the DataSource with an IQueryable object describing the query (the 300k one), then within this inherited control I want to be able to then use the filterexpression, sortexpression, pagesize and pageindex to append to the query. So the data source is provided external to this class.
== Edit 2 ==
Just to draw more attention to the crux of my confusion, one of the most baffling things for me currently is the fact that my grid is doing 3 queries:
one is to get the virtual row count from the IQueryable, that is fine returns the count as expected
the second is the unaltered 300k query, I dont have a clue why this is occuring
the third is the altered query which brings back 50 rows
As I have overridden the OnDataBinding method I do not know where else it is going to pull this data from, as the DataSource is updated before the end of the OnDataBinding to then have the altered IQueryable. So it is at some point doing something in Telerik Land to fetch this data when I dont want it to, as why do a huge query to get all data, then just query the minimal amount later? makes no sense...

Custom Pagging
Custom Sorting :- Please check "RadGrid2" in this link.
Custom Filtering
To achieve this thing i should suggest do not use AdvanaceDataBinding because it is very hard to manage with this.
Please Try to bind Radgird as we bind asp:Gridview.

Related

GridView AllowPaging = true but implement my own paging but use the asp.net pager

ASP.net webforms here, if I set AllowPaging=true and implement my own paging mechanism where I am fetching say 25 records at a time. I'd like to be able to use the default gridview pager, but it seems to be having trouble setting the number of pages. Is this an internal calculation where the ENTIRE dataset has to be binded for it to determine this calculation?
For instance, assume a query has 1000 rows and I want to only fetch 25 of them at a time. Does the gridview pager need to execute the 1000 rows as its datasource in order to get the correct number of pages (buttons) to display. I cant find a property allowing me to specify the number of pages, they all seem to be read only (get methods).
I want to avoid building my own pager...
The Effective Paging with GridView Control in ASP.NET Article describes how to implement the pagination where your gridview requests the data only for the page that is visible.
Don't be put off by the fact that the database query is executed twice. Once for the total count and another to get the page's data. For applications with high traffic or a lot of data, this approach is still more efficient than getting everything, loading into a gridview (and the view state!), sending it to the end user, and the browser loading it on the screen :).
That's where virtual paging comes in.
Set AllowCustomPaging to true.
In PageIndexChanging event, set VirtualItemCount and PageIndex to the proper value.
Put only the 25 rows in the DataSource, do a DataBind as usual, you're done.

viewstate/databinding for gridview

I have a gridview on my page that gets bound to user search results. There can be many pages upto say 1000. Each page shows 50 records. I have the built in paging turned on for the grid. I want to disable the viewstate on the grid but then I have to bind the results on every page load. (bind twice on paging). The search takes a few seconds and I would not want to store the results in the session. So, how do I achieve turning off the viewstate for the grid or is it okay to have it enabled?
This must be a very common scenario. I hope there is a standard way of doing this.
Depending on how you bind the grid view you should implement server side paging so that your only bringing back the data from the server you need to display for one page.
What data access are you using i.e. are you using linq to sql?
Heres an article on how to do it with ObjectDataSource Custom paging and sorting
Avoid where ever possible putting large amounts of info into view state as it will bloat your page and effect performance.

Binding a data source but displaying something else

I have quite a few places where I need to bind form controls directly to a backing database. I'm using LINQ to DataSet to do this.
For example, I have a ComboBox with entries filled in by a database query. The problem is of course that all of my data uses numerical IDs and I need to do a table query to translate this into user-readable options.
Normally I would just join the second table and use the combobox DisplayMember to point at the user-readable string column. This doesn't work because after using join or any projections on the query you're (understandably) unable to convert that query into a DataView.
It's hard to believe that this problem isn't run into by everyone who uses DataView. Is there any way to override my form controls' behavior to make them display a function of their value? Like if their Value is v, then they display SomeMethod(v)?
I don't believe what you are trying to accomplish is possible by means of DisplayMember. Its a property, that's how it was designed. However, there are a few other means to accomplish what you want.
1) You could wireup to the ComboBox's Format event. This is the ideal place to change your databound items into human-readable items for display, and really is exactly what you want.
2) You could use LINQ to SQL classes instead, and override the .ToString() portions in the partial classes to display the data how you want. When you databind to a LINQ to SQL object the ComboBox will display the string value of that object.
Since you are already using LINQ to DataSet, I would just wireup to the Format event, though.
I have a pretty simple approach to these things - if it doesn't play nicely, just invent a view-model, i.e. an object layout designed to make mapping between your domain model and the UI plain sailing. This can also encourage you to populate your data in the correct shape for the view-model, rather than for the domain-model; and this often has decent savings in terms of reducing the number of columns (and sometimes rows) fetched, and (perhaps more importantly) avoiding multiple trips to the DB (by fetching exactly the right data, in one hit, in the right shape).
From a view-model, you can then use simple data-binding techniques, as the data you want is now directly available as first-level values on the view-model.

How to avoid the grid view in asp.net not to post the page to the server on paging

I've a grid view, with IList as a datasource. I've thousands of records and so I've used pagination. The grid view will display only 10 records per page. My question is, how to avoid the grid view making DB calls again to the server when I click the 2nd page. Since I load all the data in a collection(IList), I need to iterate within the IList to bind data to the grid view when the next page is clicked. How can I accomplish this ? Help appreciated.
As you mentioned you have thousands of records I prefer you stay on database calls, you can reduce response time by bringing data in chunks like if you are showing 10 rows in grid view only bring 10 rows from the database. You can write a stored procedure where you can specify page size, start position, search criteria as parameters and change as per your need.
If you don't want to hit the database between postbacks during pagination, you need to store the list in memory somehow, perhaps using the Session property of the page, and then bind to that list. If the list can grow large (you mention thousands of records) I would recommend you to consider going via the database anyway, since that will preserve server memory.

DataGrid paging with persistent data

In a Sharepoint web part, I have a DataGrid with paging that I load with all of the data (not using custom paging - custom paging would require a significant overhaul in the current process and is probably one of the last options I can try). I was wondering if it was possible to have it page through the data without re-binding the data source to the grid in the page index changed event? If I remove my current calls to re-bind the data, it remains on the first page no matter what.
With a datagrid, I think you need to re-bind the grid whenever you want to go to a new page.
"A typical handler for the PageIndexChanged event sets the CurrentPageIndex property to the index of the page you want to display and then uses the DataBind method to bind the data to the DataGrid control."
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.datagrid.onpageindexchanged(VS.71).aspx
If you want to avoid querying/fetching the data over again from the source, then you'll need to "cache" the data between postbacks. There are various options here, each with it's own advantages and drawbacks.
If the size of the data is not too large and is not sensitive, you can simply put the data in viewstate on the first page load, and read it out again when the page index is changed. Another option might include using Session to "cache" the data, although this can get tricky if not done right, and of course there will be more load on the server side with this method (with varying amounts, depending on if the Session is In-Proc, State Server, or Database). There may be other methods to "cache" the data, but that is what you'd need to do in this case.

Categories