Efficient paging with Repeater, SQL Server and custom Pager - asp.net

I have just uploaded the following article to codeproject:
http://www.codeproject.com/KB/webforms/efficientpagingrepeater.aspx
Basically it is using Repeater, SQL Server with the ROW_NUMBER() OVER statement and a custom pager.
I would like to extend the pager so that it can be used multiple times on a single page and also allow previous / next buttons. I am unsure how to do that - can anybody provide suggestions / some code modifications?

CP hasn't posted the article yet, so I cannot comment on that. I can say that just about every DAL tool (EF, NH, AR, Massive, Dapper.Net, Simple.Data) all have paging built in. so hooking up paging to a repeater should not be a problem at all.
If the article is referring to a webforms server control that pages data, I would avoid it at all costs. data access should not be managed by UI components. and using any of the various DAL listed above, it's very simple to access the database using code, instead of drag-n-drop controls.
to get db paging in place you need 3 inputs and 2 outputs
inputs
sql query & parameters
starting point (page or page index)
max # of records (page size)
outputs
current page of results
total number of records
using the total number of records and the page size you can calculate the total number of pages.
var pages = total records / page size + (total records % page size > 0 ? 1 : 0);
with the page of results, current page & total number of pages you can build the UI layout

I hope this resolves your question.

Related

Selecting Sql Data Source Column Value to Variable (VB.NET)

I have a SqlDataSource, defined in the Master Page, that gets the current user permissions for the web application Select * from portal_users where userid = #userid, where portal_users is a view i built with all the data needed. I need to access the contents on the returned row so I can disable/enable site features according to the user permissions. This results in a lot of if blocks across the child pages to do it.
I browsed around forums and I only found issues about assigning those values to controls like i.e. label. Is there a way to access the SqlDataSource from the Master Page, get the row that is returned, select 1 or more column's values and assign them to variables?
Hy
It's not a good idea, use Master Page to share Data Source connections
Read this post to help you:
http://forums.asp.net/t/1188088.aspx?sql+data+source+in+Master+Page
Regards

Approach to implement lazyloading with JqGrid

I have a data source with over 10,000 records. And I want to implement lazy loading with JqGrid.
This is my approach:
Back-end: SQL stored procedure to select data by page, page size, where expression and sort(order by) expression.
Font-end: send request to get data to Web Method (web service) with: page, page size, where expression, sort expression.
JqGrid: load data to jqGrid
Here is the main issue:
- I can't overwrite the page count, records count of jqGrid. e.g. The pager info always display [page 1 of 1] and [records 1-50 of 50] if page = 1 and page size = 50.
- Thus, I can't use the paging button of jqGrid
I thought about implement custom paging infor (pages, records, paging button) but it will take time and effort. So it's better to reuse jqGrid paging, isn't it?
Does this approach good enough? Or what I need to improve?
Update: I tried to implement json reader at Can I implement lazy loading with jqGrid? but no luck.
If I need to update any information, please tell me.
Thanks in advance.

Do I need to re-retrieve data when paging using asp:GridView

I have a .aspx search screen that displays the results of the search in an asp:GridView component. There can be up to approx 1000 records returned by the search. I want to implememt paging on the grid so that only 15 records are displayed at any one time and the user can page through the results.
I am retrieving the records by passing search parameters to a WCF service which returns a List of particular entity objects. I create a Datatable and insert one DataRow per entity object from the List. I then bind the grid view to the Datatable.
This is how my grid is defined in the .aspx page:
<asp:GridView ID="gridCat" runat="server" AutoGenerateColumns="False" DataKeyNames="CatalogueID"
HeaderStyle-CssClass="fieldHeading" RowStyle-CssClass="fieldContent"
AlternatingRowStyle-CssClass="alternateFieldContent" Width="100%"
AllowPaging="True" AllowSorting="True" AutoGenerateDeleteButton="True"
PageSize="15">
and I also have this method in the code behind (.aspx.vb file):
Sub GridPagingAction(ByVal sender As Object, ByVal e As GridViewPageEventArgs) Handles gridCat.PageIndexChanging
gridCat.PageIndex = e.NewPageIndex
gridCat.DataBind()
gridCat.Visible = True
End Sub
My problem is this: the first page is rendered correctly i.e. the first 15 records are displayed correctly. However, when I navigate to page 2 in the grid, the GridPagingAction method is hit on the server but nothing is displayed in the grid - it is just blank.
I think the reason this is happening is because the Datatable no longer exists on the server when the request for the second page hits the server - is that right? And the asp:GridView, when it is rendering the first page of results, only takes the first 15 records from the Datatble and sends them back to the browser. So when the request for the second page comes in the other records (i.e. records 16 - 1000) don't exist anywhere - is all that correct?
If so, what's the best solution - I can't see how to implement paging without having to do one of the following:
re-perform the search each time the user uses the paging option;
saving the search results on the Session after the first Search retrieving them each time the user uses the paging option;
manually inserting the Search results into ViewState and retrieving them each time the user uses the paging option.
Is there a better way to do this (or am I doing it wrong)? If not, which of the 3 options do you think is the best? I'm leaning towards option 2 as I don't think option 1 is performant and I don't want to be sending loads of unnecessary data back to the browser as per option 3.
All you said is correct. You could either use ViewState or the Session to keep hold of the data on client- or server-side, but if you really have that many records, it might be a good idea to only collect the data you actually need.
So if you want to show records 1 to 10, you perform a query against the database and only fetch those ten records. If you want to show the next ten, you perform another query with the according parameters.
This will improve your performance and memory usage significantly, IF calling your DB is not overly expensive.
This article might give you a start on how to do this:
http://dotnetslackers.com/articles/gridview/Optimized-Paging-and-Sorting-in-ASP-NET-GridView.aspx
If you want an easy solution without any additional efforts, I would query all the records on each postback (your option #1).
If you want the best performing solution with not much overhead, use the custom paging.

Limit rows in table per page

I would like to be able to limit the number of rows that can be in table on View page (I am using ASP.NET MVC), and if there are more rows, it goes to the next page.
Pretty simple :
var query = /* your Linq query */;
query = query.Skip(itemsPerPage * pageIndex).Take(itemsPerPage);
You will have a lot more luck finding the answer, if you say paging.
this is one approach
Asp.net mvc isn't like the regular asp.net, where you can get by without knowing a bit more of the underlying stuff.
Also note, that how exactly you implement paging in the controller & get the set of page links, depends on how you are getting a hold of your data.

asp.net custom datapager

in all the datapager examples i've seen (using a LinqDataSource tied to a ListView) the queries to the database return the full recordset. how can i get JUST the page of rows that i want to display?
for example, if i have a table with 1million rows and i want to see the 10 results on page 5, i would be getting rows 51 to 60.
i'm sure i have to implement custom paging but i haven't found any good examples.
There are many ways of doing this, however, I personally like a SQL based solution that goes to the database and gets the result set. This 4GuysFromRolla Article does a good job of explaining it.
If you're using MSSql2005, take a look at this article.
As you can see, the trick is to use the function ROW_NUMBER(), that allow you to get the sequential number of a row in a recordset. With it you can simply enable pagination based upon the number of rows you want to get in a page.
I was under the impression (from Scott Guthie's blog post "LINQ to SQL (Part 9)") that the LinqDataSource handles the paging for you at the database level:
One of the really cool things to notice above is that paging and sorting still work with our GridView - even though we are using a custom Selecting event to retrieve the data. This paging and sorting logic happens in the database - which means we are only pulling back the 10 products from the database that we need to display for the current page index in the GridView (making it super efficient).
(original emphasis)
If you are using some custom paging, you can do something like this in LINQ to SQL:
var tagIds = (from t in Tags where tagList.Contains(t.TagText) select t.TagID).Skip(10).Take(10).ToList();
This is telling LINQ to take 10 rows (equivalent to T-SQL "TOP 10"), after skipping the first 10 rows - obviously these values can be dynamic, based on the Page Size and page number, but you get the idea.
The referenced post also talks about using a custom expression with a LinqDataSource.
Scott has more information on Skip/Take in Part 3 as well.

Resources