whats are methods to keeping datasource for a gridview.
situation :
I have a query which can take 5 to 10 seconds (a lot of link on a lot of data).
The result is too big for a page so I have a paging on my grid.
But, every time I use the pageIndexChanged, I need to get the datasource again.
So I want to know how I can keep my datasource.
Is it possible? NOT by session.
It is possible, I have used a custom (server-side) viewstate provider to cache your datasource.
*Updated: There is a pretty good article on custom viewstate providers (with sample code) here: http://www.codeproject.com/Articles/8001/ViewState-Provider-an-implementation-using-Provide
However, I would strongly recommend improving your query to limit the data to that which the user really wants to see. Large grids that have many more rows than the user is truly interested in are unwieldy from memory, processor, bandwidth, and user-experience perspectives. Try to find a better way.
Related
I'm populating a GridView with code, setting datasource to the dataset returned by a query. So apparently sorting and paging don't just work magically like if I use a datasourceid= some sqldatasource.
I've found a number of examples of how to do this on the web, but they all appear to re-execute the query every time. Shouldn't the contents of the query be saved in the view state? Is there some way to just get the previous query results and re-sort without having to go back to the database? (Is it saving all the data in the view state? If so, why can't I get to it? It seems pretty dumb to send it all to the user's browser and send it all back, wasting all the bandwidth, if there's no way to get to it.)
Also, if I try to allow paging, it appears I again have to re-execute the query every time the user goes to another page. And if the user sorts and then pages, then I have to remember what the sort order was in a hidden field or some such, so I can re-read the data, re-sort, and then go to the right page.
Given that when you use a data source control all this behavior is built in, I think I'm missing something here. But given all the examples out there that do it this slow, hard way, if I'm missing something, a lot of other programmers are missing it, too.
If you're using an ASP.NET GridView control every time you sort a column or page through the data set then you're making a server postback. Sorting and paging with this particular control has never worked 'magically' and has long been a bugbear of mine.
You can speed things up by storing the data source that you're building the grid from in memory, either as a session or through the ViewState. Both have pros and cons and I suggest you read up.
If at all possible I suggest forgetting the ASP.NET GridView and looking at a client side solution such as the jQuery jqGrid. It uses AJAX calls to sort and page and is much, much faster and less of a headache. The only drawback is the learning curve but believe me it's worth it in the long run.
Yes the gridview re-execute the query every time.
If the query takes too long, you can manually store data in the session, or ViewState. And in the Algorithm that populates the grid just read them directly for it, instead of running the query.
you can, in the page load event, run the query one time when there is no postback (you can check for postback with
if (!Page.IsPostBack){
//Run the query and save it to the session
}
and the the method that populate the grid, should read from the session directly. no need to run the query again
I used bind all GridViews, DetailViews etc. on my page using an ObjectDataSource (unless it wasn't possible to do so). Recently, I've started binding all my contols programatically. I find this a lot cleaner and easier, though some may disagree.
Binding with a ObjectDataSource obviously has it advantages and disadvantages, as does doing it programatically.
Say I bind a GridView programatically (e.g. GridView1.DataSource = SomeList), when I change page on the GridView, I have to also code this. Each time the page changes I have to call GridView1.DataSource = SomeList again. Obviously with a ObjectDataSource I don't need to do this. I normally stick my SomeList object into the ViewState so when I change page I don't need to hit the database each and every time.
My question is: Is this how the ObjectDataSource works? Does it store it's data in the ViewState and not hit the database again unless you call the .Select method? I like to try and get the best performance out of my applications and hit the database as few times as possible but I don't really like the idea of storing a huge list in the ViewState. Is there a better way of doing this? Is caching per user a good idea (or possible)? Shall I just hit the database everytime instead of storing my huge list in the ViewState? Is it sometimes better to hit the database than to use ViewState?
Does it store it's data in the ViewState and not hit the database again unless you call the .Select method?
No its not save the data in ViewState. In the view state gridview and other similar lists, saves the General Status, eg the sort column, the page, the total pages, the control state, but not the Data.
Is caching per user a good idea
The caching per user on server side is not so good idea except if the caching is last for few minutes only or/and the data that you going to cache is very small. If you cache per user large amount of data for long time they going to grow too much especial if a user starts to read a lot of pages, that at the end you have the same problem.
Now you have to show a large amount of data that come from the relation of many tables, then maybe is better to cache the full relation of the tables to "one flat table".
Shall I just hit the database everytime instead of storing my huge list in the ViewState?
This is also depend from how fast you have design the reading of your data. For me is better to keep the ViewState small, and keep there only informations that you need to make the actions on your page, and not data.
I have a gridview with about 300-400 rows that I use for reporting; it needs paging and requires sorting. My choice is between these two options: a) load the 300-400 in one query and let the gridview do the paging and sorting; b) handle the paging/sorting at the data source level. I know that b) is going to be better/faster/more efficient... In my context, I'm looking to get something done relatively fast; if I choose a), will the page seem incredibly/painfully slow?
Thanks.
Use the builtin functions of the GridView and load the whole data at one go. It wouldn't be worth the effort to implement paging in database(f.e. with RowNumber) when your number of records is such small, especially because you mentioned that you are looking for a fast solution. When you enable paging in GridView the performance will suffice.
read Scott Guthrie's excellent article about paging.
How to implement a data-result search page built with ASP.NET 2.0 and Atlas that can present hundreds of thousands of row results using the ASP.NET 2.0 GridView control. The results are formatted using a “paging” based UI model – where 15 results per page are displayed, and the user can skip from page to page to see their data. For kicks I also added support for editing and deleting each individual row.
Although 300-400 rows isn't a particularly large set of data, I would certainly vote for option B since it will definitely be more scalable. Once you start getting massive sets of data, loading all of it with one query and having the GridView handle the paging will end up being incredibly slow. The better option is to, like you said, only query the data you need for each page.
However, if you aren't going to have data sets larger than 300-400 records, you probably don't need to be too concerned about load times, but again, the key is in scalability.
Say I have 2 tables in a database, each with 100,000's of rows in detail and 10,000's of rows in the master 5 columns each, properly indexed and related. I want to have master/detail nested gridviews. What's the fastest architecture I could design in .net to do this? The largest result set on the master could be in the thousands (usually in the tens though) and the detail per records could be in the hundreds (usually in the single digits though). I'd like to be able to do a display all masters if possible.
The bottom line: bind to DataReaders, use Repeaters instead of GridViews, and turn off ViewState.
The design you're proposing is going to be pretty hard on your users (thousands of records, yikes), but you probably already know that.
If this is just for display and you want the absolute fastest architecture for Asp.Net, you should obtain an IDataReader for each data segment (master and child), sorted such that you can manually match child records while reading both resultsets in a forward-only fashion. (See Scott Mitchell's Why I don't Use DataSets in my ASP.NET Applications for some details about DataReader performance - as long as you aren't optimizing prematurely, it's quite good advice.)
Instead of using a GridView, I'd use a Repeater which has less overhead and lets you write more compact HTML (for a smaller payload to the client): bind the master IDataReader to that repeater. (I'm not sure whether you meant the GridView control, or just a conceptual grid - the basic architecture would be the same for a GridView)
Then add a handler to the Repeater.ItemDataBound that checks if the child data reader's current record matches. If it does, manually render your detail data for that master record.
Finally, you should also turn ViewState off, at least for the Repeater (preferably for as much of the page as possible), again so that the HTML payload is smaller.
If you're totally committed to nested GridViews, particularly to using a GridView to render the detail data, it's going to hurt the performance one way or another, because you'll have to either make many more database calls (to obtain discrete resultsets you can bind to) or you'll have to massage the detail data into an intermediary container.
I'm writing an internal web application that is used to look up credit checks. I'm using ASP.NET for this website.
I have a SQL Query that I have to query the credit check database and it returns a datatable of results. After the person clicks search, I run the query and bind the returned datatable to the Gridview every time the user clicks the search button.
This works fine, and it populates my gridview like it should.
How do I maintain the data that is bound to my gridview beyond postback? For example, lets say a person clicks Page 2 of the paginated gridview... how do I keep from losing the data of the gridview during that postback?
Currently I am storing the datatable in session[] but I don't think I should be doing this, because the size of this table is very large (sometimes hundreds of thousands of results!)
Do I need to re-query the database for each postback? The query takes a decent bit and I'd rather not if I could help it.
What is the common solution here?
If you are storing the data in the session I would make sure viewstate is turned off and you are rebinding it on each postback so at least your not storing all that data in 2 places.
You could also considered leaving the viewstate on and changing logic that grabs the session data to bring back one page of data at a time? You would take in the current page and JUST return that page's data so that you could get all the data at first and store it in the session. Then if any other postback actions occurred during that page view where nothing was really going on with the grid you wouldn't have to rebind each time.
I have found that most of the issues I have run across in the past due to too much data being displayed in a grid were more design issues and I would step back and look at the overall problem that was trying to be solved and implement another solution to not have to display so much data. Usually a customer/user asks for everything because they don't consider any alternatives or the impact of their request.
Several things:
Clicking on "Page 2" should not result in a postback - it should be a simple GET request.
Do not allow GridView to store its data in the ViewState: cache data manually and "rebind" datasource on each request
Use ASP.NET MVC