Hi guys,
I am in the process of evaluating the aspxGridView and i have to say its fantastic. However I have come across a situation and I am struggling to find a way through it. I do most of the paging, sorting, grouping and filtering at database level for maximum performance and overcoming memory issues. E.g. Paging at database level is done by passing gridview PageSize and first row index of the current page as parameters to the business logic methods, which in turn passes these two parameters to the data access provider method. The dataaccess provider method uses these two parameters (PageSize and StartRowIndex) to only retrieve the desired set of rows instead of returning all the rows from the database. So e.g. if there are millions of rows and the gridview page size is 10, instead of returning million rows in memory, only 10 rows are returned, keeping the server memory free.
I know aspxGridView is very fast and perform paging, sorting, grouping and filtering in seconds for thosands of rows but I still think its a better approach to perform all these functions at the database level.
So with the normal asp.net GridView, there is a way to automatically pass these two parameters to the business object method by setting the ObjectDataSource EnablePaging=true and defining SelectCountMethod. Most of my business objects method expects the PageSize and StartRowIndex parameters.
The above is not working with the AspxGridView & ObjectDataSource though. I receive values of 0 for both the parameters in my business logic methods. I am sure there must be a way to get hold of these values. Infact not just the page size and start row index, I would also like to know how to pass sort, filter and grouping expression to my business logic methods, so that I can do all this stuff at database level in my sql queries?
Awaiting
Nabeel Farid
Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.
Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.
Hi Nabeel,
Thank you for the detailed description of the problem.
I understand the functionality you wish to achieve, but I'm afraid there is no easy way to do the same thing when working with ASPxGridView. Please look at the following report to learn more on this subject:
ID: Q100566, Sort the grid at database level!
So, the only thing we can suggest is to implement the IListServer interface at your datasource level, as suggested in this report (please note, this is not an easy task) or work with the grid in Server mode. Please look at the following help topics to learn more:
Server-side Data Management
LINQ Server Mode
However, in this instance, you'll have to substitute your ObjectDataSource with either LINQServerModeDataSource or XpoDataSource.
Thanks,
Vito
Hi Vito,
Thanks for the quick response. I have gone through all the info and suggested article you provided and I am a bit confused.
I don't understand why a basic feature that was already there in the ASP.NET Gridview/ObjectDatasOurce is not available in your advance gridview. Why can you not just add this feature to your grid, so that the pagesize, rowindex, filter and grouping expression can be passed to the business objects method via object datassource in some form of string or predefined xml format or something.
I have been evaluating Obout Grid and they provide the same simple method of passing all the parameters via object datasource in a propreity string format, whch can easily be parsed to build a sql query. Infact they got two modes, client side and server side. In server mode all the sorting/paging/groupin/filtering can be done at database level manually via string expressions passed through the grid/ & objectdatasource. Can you not provide the same feature. That would be fantastic. You mentioned "claculation of group and summaries", we can do that at database level by ourselve as well. Just provide us the expressions. Also, just like we write "SelectCount" method to aid paging with objectdatasource we can also write a couple of more methods for calculating group and summaries based on if it is required or not :)
I read about IListServer implementationa and it seems too complicated. I also read and watch the webcasts of XPO and LinqServerModeDataSource by Mahul and the preference of LinkServerModeDataSource over XPO. but then again its all done by creating a separate DataAccess layer (the .dbml file or object persistence classes) with data tables. What about my Business Objects and their methods? I would like to bind my business objects to the grid instead of the dbml tables. Is there a way to do it?
Also the linqservermodedatasource TableName property allows it to point to one table only. My Select queries involve complex joins. How would i achieve that.
All this seems like a whole new learning curve and contradict the whole point. I was expecting to replace the existing UI in our systems with some rich UI and some extra functionality without the need of binning or rewriting our business logic and dataaccess layers.
I have also notice that the Grid keeps binding itself everytime there is a postback even via a button click outside the grid that has got nothing to do with the grid at all. Doesn't make any sense? it keeps calling stored procedures, wasting processing time and memory on the server? Is this the normal behavior? Is there a way to disable it or somehow cancel the binding when it is not required ? I understand that it needs to rebind when clicked for paging/sorting/grouping but why it does that for a button click that is not defined in the grid and has got nothing to do with the grid at all?
Awaiting
Nabeel
Forgot to mention that the implementation of IListServer at http://www.devexpress.com/Support/Center/e/E166.aspx only supports paging and does not support filtering, grouing and summary either. So does that mean if i want to have database level paging along with filtering, grouping… I have only got linqservermodedatasource option?
Just read in the documentation that the DataSourceForceStandardPaging property of aspxgridview enables the capability to pass default data source paging parameters to the ExecuteSelect(). So I assume this means there is no need of implementing IListServer interface if only paging and sorting is to be done on database level? But to have the grouping,filtering and summary calculation along with paging, IListServer implementaiton of the datasource is required (e.g. LinkServerModeDataSource). Please correct me if I am wrong? And also how would I use LinkServerModeDataSource with my business objects?
Awaiting
Nabeel Farid
Hi guys
Could you please answer my following queries:
Awaiting
Nabeel Farid
Hi Nabeel,
Indeed, the DataSourceForceStandardPaging property is the thing that you should use in your application if you need only server side paging and sorting. If you also need to support grouping, filtering, summary you need to support the IListServer interface in your DataSource class.
>>
And also how would I use LinkServerModeDataSource with my business objects?
<<
This depends upon your business objects and it is difficult to answer your questions not having your code.
Here are answers to your questions:
4:-) The LinqServerM odeDataSource provides the Selecting event which can be used to pass a custom queryable object. It can be used to fetch data from the underlying data store.
Thanks,
Plato
Hi Nabeel:
We're working on this issue and will answer you as soon as possible. Please accept our apologies for the delay.
Thanks
Kate.
Thanks for the reply Plato. I have got few more queries.
Awaiting
Nabeel
Hi Nabeel,
Thanks,
Plato
Hi Plato,
Thanks for your response. I have got following queries :
I have managed to implement Paging and Sorting at database level using ObjectDataSource parameters PageSize, StartRowIndex and Sort Expression but I would like to have Grouping, Filtering and Summary Calculation features as well.
Awaiting
Nabeel
Hi Nabeel,
Thanks,
Plato
Hi Plato,
Thanks for sending the sample. I have found out why the Select method is being called every time there is a post back in my code.
The reason is I am binding the ASPxGridView to a collection of custom objects and I am handling ASPxGridView's HtmlRowCreated event in order to manipulate some web controls contained within the template columns. I am using ASPxGridView.GetRow(e.VisibleIndex) method to retrieve the underlying custom object as follows:-
protected void ASPxGridView1_HtmlRowCreated(object sender, ASPxGridViewTableRowEventArgs e)
{
ASPxGridView gv = sender as ASPxGridView;
//process only data rows
if (e.RowType != GridViewRowType.Data) return;
//get underline custom object
CustomObject obj = gv.GetDataRow(e.VisibleIndex) as CustomObject ;
if (obj == null) return;
else
{
// do something
}
}
I have noticed that on a post back, HtmlRowCreated event is always called for each row, even on a button click outside the grid. And as soon as the GetRow() method is called for the first time in HtmlRowCreated , it goes into the Select method.
Now what I would like to know is, if this is the right behavior, then how do i get the underlying custom object? The underlying custom object is complex and have some child objects in it which I need to access in order to manipulate the web controls contained within the template columns.
I have attached the sample you sent modifying it a bit to replicate the behavior. Please have a look.
Regards,
Nabeel
Hi Nabeel,
This is the correct behavior. The grid is able to render using only values saved in its cache. However, if you need to obtain an object, the grid should bind to the DataSource. I do not see another way for the grid to obtain this object. Anyway, you can use your DataSource methods and locate the object by the e.KeyValue passed to the event handler.
Thanks,
Plato
Hi Plato,
I am a bit confuse with your response. First you are saying that the grid caches the data in order to render but then you are saying that if it needs the custom object it has to bind. Well if its caching the objects when the page loads first time then why does it need to rebind on the postack? Shouldn't it get the data from the cache? what would be the point of caching then?
When the page loads first time, the Select method is called and in the HtmlRowCreated event for each row, e.GetRow() method works normally without calling the select method again. However when the postback happens e.g. a button click, the HtmlRowCreated event is called again for each row, but this time, the first call to e.GetRow() results in calling the Select method. Why is it making the call to Select method if it is already caching the data ?
Regards,
Nabeel
In the standard asp.net grid, the underlying object can be retrieve by casting e.DataItem in the RowDataBound event, but RowDatabound event is raised only if the grid is bind. In ASPxGridView , HtmlRowCreated event is raised not just when the grid is bind, infact it is raised everytime there is a postback. The code in the eventhandler requires the underlying data object to render template cells properly. I do e.GetRow() to get the data object. It works fine when the page is load first time but on a postback it results in calling Select method, which is a total waste of time and memory. I should be able to get it from the cache rite? How should i do that?
Awaiting
Nabeel
Hi Farid,
The grid caches values for its cells. This cache is stored in a hidden field. We do not cache objects as it is possible that we won't be able to deserialize them from a string. The Select method is called, because you are asking the grid for a data object. If there is a value in the cache and you need it, the Select method is not called.
>>
In the standard asp.net grid, the underlying object can be retrieve by casting e.DataItem in the RowDataBound event, but RowDatabound event is raised only if the grid is bind
<<
Yes, you are right. Why do you need to obtain a row object when the ASPxGridView is not bound to the DataSource? If you need to know whether the grid was bound to the DataSource during the current request, handle the gridView's DataBound event.
Thanks,
Plato
Thanks for your response. I think I need to explain you again what I am trying to achieve. There might be another way using aspxGridview.
I am using aspxGridView with an ObjectDataSource that binds to a collection of custom objects(a list of Customer class objects). The customer class has two properties: Name and Address. The Address property is an object of type Address Class. Inside the grid I have a TemplateDataTextColumn in which I have an aspxLabel . The text property of the label is bind to the Customer class Name property. Now what i would like to do is to make the label forecolor green if the customer Address is not null and red if the Address is null.
When using the standard asp.net gridview, I normally achieve this in the RowDataBound event casting e.DataItem to the customer object and then using e.Row.FindControl() to get the label and then finally checking if the custom objects' Address property is null or not and change the color of the label accordingly.
I am trying to acheive the above with aspxGridView in HtmlRowCreated event and using e.FindRow() to get the Customer object. It works fine when the page loads for the first time. However if a postback occurs (anywhere on the page), HtmlRowCreated is raised again and e.FindRopw() results in Select method call, wasting memory and time. In standard asp.net grid, the RowDataBound event does not get raise for a postback, so no calls to select method is made.
So Is there a way where i can achieve the above, without calls being made to select method on postback, just like standard asp.net grid? The calls to Select method for every postback is just not acceptable. May be I should not be doing this in HtmlRowCreated event? Is there another event? Should I do this in DataBound event ? How? Help please
Awaiting,
Nabeel
Hi Nabeel,
Thank you for the explanation. I will try to create this project for you using the ASPxGridView. If you send me a GridView-based project, illustrating the desired functionality, this would be of great help.
Thanks,
Plato