I am curious to know how does paging work in asp.net?
If my query returns 500 records, and my gridview paging limits to 25 records per page, when the gridview loads, does the recordset return 25 records or 500 records?
If the recordset returns 25 records, how does ado communicate with SQL to return records for page two?
If the recordset returns 500 records, are they cached within the client side?
From MSDN:
the GridView control will perform
paging by getting all of the data
records from the source, displaying
only the records for the current page,
and discarding the rest.
So the answer is, it doesn't really do efficient "paging", like many aspects of Web Forms, its all abstracted away. It's not really doing a "SELECT TOP 10".
It's simply disregarding the records it doesnt need - but the DB call is still a "SELECT *".
That is why many people (myself included), prefer to write custom yet simple paging with LINQ, using the Skip and Take IEnumerable extension methods.
E.g
yourDbContext.Where(s => somePredicate).Skip((pageNum - 1) * pageSize).Take(pageSize);
You might want to depend on client side pagination approaches via javascript. jqGrid is an excellent jQuery based solution. Of course this would mean that you'd have to load the entire data on the page. Else you'd need to write your stored procedure to return data from a particular page. But in this case you'd have to implement your own paging techniques. Such stored procedures you create must always return two result sets. One that returns the actual data, and the other resultset which returns basic pagination info, like total no.of records, total pages, & current page.
Related
I have a Page with a Table for which its datasource is a relation and needs to be sorted based on fields from another model:
Page
Datasource = Indicators
Table
Datasource = Indicators [one] : MetadataText [many] (relation)
The Table needs to be sorted based on a field from another Model called MetadataField, which has a one to many relation with MetadataText.
I have the datasource of MetadataField sorted. But the content in the Table appears in random order. When I first access the application, the Table is sorted by the order that the records were loaded. After view some records, the sorting of the records changes and keeps changing.
I am using Google Drive tables.
You can easily sort related records by one of the fields that belong to the related record itself, but only once (you'll received those records sorted from server).
But it seems, that you want to sort related records by their related record. App Maker will not be your friend in this case... but javascript will be! Since App Maker loads all related records you can safely sort them on client using javascript:
indicatorsDatasource.load(function() {
indicatorsDatasource.items.forEach(function(indicator) {
indicator.MetadataTexts.sort(function(a, b) {
return /* here goes your sorting logic */;
});
});
});
It will work in O(n * m * log(m)) in case you have n Indicators on the page and every indicator has m associated MetadataTexts. If you want to let users to sort related records by clicking table's header, you'll need to implement that logic on your own. So... all this hassle leads us to alternative solution! What if we decouple related records and introduce separated datasource for them? Having that you'll be able to use full power of App Maker's tables (sorting/paging) with almost no effort. You can take a look at implementation sample in Project Tracker template ViewProject page.
We are creating an application MongoDB as database and we are using official C# driver for MongoDB. We have one collection which contains thousands of records and we want to create list with paging. I have gone through documentation but there is not efficient way of paging with MongoDB C# official driver.
My requirement is to exactly fetch only 50 records from database. I have seen many examples but that get all collection and perform skip and take via LINQ which is not going to work in our case as we don't want to fetch thousand of records in memory.
Please provide any example code or link for that. Any help will be appreciated.
Thanks in advance for help.
You can use SetLimit on the cursor that represents the query. That will limit the results from MongoDB, not only in memory:
var cursor = collection.FindAll(); // Or any other query.
cursor.SetLimit(50); // Will only return 50.
foreach (var item in cursor)
{
// Process item.
}
You can also use SetSkip to set a skip (surprisingly):
cursor.SetSkip(10);
Note: You must set those properties on the cursor before enumerating it. Setting those after will have no effect.
By the way, even if you do only use Linq's Skip and Take you won't be retrieving thousands of documents. MongoDB automatically batches the result by size (first batch is about 1mb, the rest are 4mb each) so you would only get the first batch and take the first 50 docs out of it. More on
Edit: I think there's some confusion about LINQ here:
that get all collection and perform skip and take via LINQ which is not going to work in our case as we don't want to fetch thousand of records in memory.
Skip and Take are extension methods on both IEnumerable and IQueryable. IEnumerable is meant for in memory collections, but IQueryable operations are translated by the specific provider (the C# driver in this case). So the above code is equivalent with:
foreach (var item in collection.AsQueryable().SetLimit(50))
{
// Process item.
}
I need help choosing between Telerik RadGrid and DevExpress ASPxGridView for Asp.Net based on unique filtering requirements. The data lives in denormalized Vax files. All data access is via Sql Server stored procedures calling ODBC Connx queries to the flat files. Stored procedure parameters are used to filter the data. Without any filter thousand of records are returned.
I've successfully displayed all records on two test ASP.net pages, one with DevExpress ASPxGridVIew and the other with Telerik's RadGrid. In code I databind each grid to the stored procedure that returns over 26,000 rows. The sproc is called via an Entity Framework function import that fills an IEnumerable<Customer> which becomes the datasource of each respective grid. I'm able to use the filter features of both grids and they seem to work nicely.
My problem is that before the grid filter is applied all of the thousands of rows are returned from the stored procedure. I'd like to intercept the grid's filter parameters and apply them to my stored procedure parameters. That way far fewer records will be accessed.
Can this be done with either 3rd party grid and if so how?
Thanks in advance.
It seems it can be achieved using a RadFilter to the RadGrid. One example here.
But in general, looks like you'd need to add a handler to ItemCommand, and perform the appropriate filter based on the CommandName, for example. You could then just rebind the data.
The Rad Filter will also allow you to use it without being directly tied to another control or datasource. The filter has an option to extract a filter expression in many different forms (linq provider is one of them). You can then apply that expression to your datasource. We are doing something similar. We have a page where we dynamically create the rad filter with the types of fields and filter options. The user then uses the rad filter UI to create the filter based on the desired fields, then we extract a filter expression we can apply to a datatable that is created on the page that shows the data.
Here is the code for extracting the filter expression from the filter:
var provider = new RadFilterSqlQueryProvider();
provider.ProcessGroup(myRadFilter.RootGroup);
var sqlFilterExpression = provider.Result;
I have a gridview which contains 100 records i have set paging to 10. At page_load it fills the grid so the records are not going to change so i dont need to hit to database again.
There is a filter textbox availble at the top of 'Name' Column when user types some key it should filter the 100 records & should return the matched records (e.g using Contains filter).
It is not very difficult task if i user update panel. But, It takes time becoz i am fetching records on each key. Even i use viewstate it slows down the performance. Is there any alternative way to achieve this? I am wondering if u could use some javascript logic
If you are ok with implementing server side instead of with javascript, you could store the data in the cache object on first load, and then pull from cache on each subsequent hit.
A very simple example
How to keep custom paging for dynamic result sets ? (i.e) based on 10 Dropdowns selection my stored procedure will Dynamically generates resultset,but it populates million records.
Row statically know Record count,cusom paging is efficient,but how to achieve it for dynamically grown result set?
Problem
I have to bind generic List to GridView,Columns are fixed,but the number of rows retuened are unknown,but without custom paging my GridView took 30 minutes to populate the result.
If possible, you should use LINQ, as the extensible operations make for easy paging.
Essentially, you would specify an ObjectDataSource or LinqDataSource for your GridView.
You would then have an IQueryable<T> method which accepts a starting position and number of rows to retrieve.
Then you make use of Skip() and Take() to achieve simple paging.
Here's a very good article on doing that.
Remember that Skip() and Take() are methods exposed to any class which implements IEnumerable. So even though the above article uses LINQ-SQL for their data repository, as long as your own DAL exposes a collection of type IEnumerable, you can use the Skip and Take pattern.
Hope that helps.
An easy way to do this server side would be to use LINQ. Took at the .Take() method.