Using
Windows Forms DataGrid with ADO.NET
Host: Nauzad Kapadia, Microsoft MVP
March
14, 2003
Deepak_MS: Hi Everyone!
Deepak_MS: Today we have with us Nauzad Kapadia. Nauzad is CEO of
Mumbai Based quartz systems - http://www.quartzsystems.com/ and is
a Microsoft MVP
Deepak_MS: Today he will discuss with us Windows Forms DataGrid and
how you can use it with ADO.NET
Deepak_MS: So over to you Nauzad..
nauzad: Hi everyone.... let the fun begin !!!
Deepak_MS: Since we don't have any questions why don't you give a
brief intro on the data grid control and how things have changed since
ado days..
Deepak_MS: (Naveen): I've migrated a legacy application, written in
VB-ASP to ASP.NET. The pages and business logic are identical. On
my local LAN, the ASP.NET application is faster and more sclable.
But on a WAN (2 LANs connected through a 2 Mbps link) the ASP.NET
application is 1.5 - 2 times slower. This led me to capture packets
(using a packet capture tool called "ethereal") and then count the
number of packets transacted per HTTP request. I found that though
the ASP.NET produced pages are smaller by a factor of 0.75 compared
to the legacy pages, the number of packets transacted between the
client and the web-server is 1.44 times higher compared to the legacy
application. Why?
Deepak_MS: Why does ASP.NET transact more in terms of packets exchanged?
Is there a way to overcome this problem?
nauzad: one of the reasons u see the higher number of
packets transferred is because ADO.NET uses a higher footprint than
classic ADO and this is because ADO.NET uses XML behind the scenes
for everything.
nauzad: and I am sure u must be aware that XML is very
verbose and that should explain the higher payload factor
nauzad: to overcome this problem, you can not use a dataset
and instead use datareade also make sure u turn the viewstate for
the DataGrid off. The drawback is that you might have to implement
your own paging/sorting algorithm. I hope that answers your query
Deepak_MS: To that I would like to add - asp.net uses postbacks for
a lot of things. Make sure you are using client side validations for
uplevel clients.
Deepak_MS: A lot of people are confused about DataReader and DataSet,
Nauzad, in a winforms application which one should be used - can you
illustrate scenarios for each of them?
nauzad: A DataReader is analogous to a readonly static
recordset that we had in classic ADO
nauzad: A DataSet is everything your recordset used to
be (and much more) and of course its disconnected.
nauzad: Typically in a winform app. there are very few
scenarios where u would use a DataReader. One common scenario would
be when you want to process a set of records sequentially for some
data processing tasks
nauzad: however DataReaders really come into their own
in web applications... where most of the time using a dataset is an
overkill and not really necessary
nauzad: hope that clears some confusion.
Deepak_MS: Here is another question that I see frequently - lets say
I have an Editable DataGrid bound to a dataset. Now dataset is disconnected.
I make some changes to data in the DataGrid, now I want to commit
changes back to the database... how does ADO.NET handle the scenario
where some of the records have been changed by another user?
nauzad: ok.. how does ADO handle updating records is one
part... handling concurrency (records modified by another user) is
another part.
nauzad: when you bind your DataGrid to a data source,
whatever changes are made to the data in the grid, they are automatically
propagated to the underlying data source. the grid handles ending
the "current operation" etc.
nauzad: so calling the update method on your DataAdapter
will propagate your changes to the database... of course this is assuming
that your DataAdapter has been properly set up with the correct command
objects
nauzad: to handle concurrency, ADO.NET uses optimistic
concurrency, where while updating each record it checks to see if
the record that was modified by someone else before you could update
your changes.
nauzad: if yes, then it automatically adds a "RowError"
and stops updating any further records. The grid automatically picks
up the RowError and displays a little red icon next to the row.
nauzad: The default behavior of the DataAdapter (which
stops updating other records if an error has occurred), can be changed
by trapping the Row_Updated Event, and setting e.status to UpdateStatus.SkipCurrentRow
Deepak_MS: How do I override the record modified by other users -
i.e. I want to commit the changes that I made?
nauzad: In that case, you will have to create your own
insert query and execute it using the command object.
nauzad: after you do that make sure, that you call the
AcceptChanges method on that particular row so that when u call DataAdapter.Update
subsequently, it will ignore that record.
Deepak_MS: Now it is possible to have more than one DataTable in a
given dataset - can these tables have some kind of relationships?
nauzad: yes, if you have defined relations in your dataset
(using DataRelation object) and if you bind your grid to the parent
table...then the DataGrid shows a neat little "plus" sign next to
every row .... like it does in access 2000 onwards.
nauzad: expanding the plus sign will show you all the
related records for that particular parent record... a very nifty
feature. works really well when you have a kind of master-child-child
kind of a form. Earlier we would do it with 2 DataGrids, which would
cramp the form... now its so much more elegant and simpler.
Deepak_MS: Coming to more conventional "DataGrid-less" applications.
Suppose we have a "normal" form with textboxes/list-boxes etc bound
to a DataSet... could you illustrate the flow of data from flow to
the DataSet and then from DataSet back to the backend
nauzad: You can bind your textboxes and any other control
using the "databinding" features.
nauzad: whenever u make any changes to the controls, they
are automatically passed on to the underlying datasource (just like
the DataGrid)
nauzad: however these controls do not end the current
edit operation automatically
nauzad: so when u change some values, the RowState does
not change (it remains "Unchanged") and therefore if u call the UPDATE
method, these changes will not be saved in the database. So you will
have to manually call the "EndCurrentEdit" method of the BindingContext
or the "EndEdit" method of the DataTable
Deepak_MS: (Kaustav): hello, I have one query, what would be the easiest
way to add data through a DataGrid. It seems it's not the same as
updating or deleting data from the DataGrid?
nauzad: hi Kaustav... I hope you are talking about a winform
DataGrid
Deepak_MS: (Kaustav): Actually I mean the ASP.NET DataGrid
nauzad: oh!!! ok.... web applications are a complete different
ballgame
nauzad: in a webapp, typically there is no concept of
"adding" a new row to the grid.
nauzad: you will have to provide a ADD button somewhere
on your form
nauzad: on click of that button, you would manually add
a row to your data source.. this row would have default values assigned
to all the columns (space for character columns, 0 for numeric columns)
nauzad: then you bind this datasource to your grid, and
viola ... you get a blank record right at the end... of course u have
to make sure that you set the EditItemIndex of the grid to the row.
Deepak_MS: (Naveen): is it possable to use a DataView as a source
to define another DataView?
nauzad: no you can only use a DataTable
nauzad: however you can achieve this by taking the "where"
clause of the first DataView and "anding" it with the "where" clause
that you want to use for your derived DataView
nauzad: it would give u the same results.
Deepak_MS: (Naveen): I have to do a report that runs by department
and then add a summary of the report by the entire company. The problem
is that the report includes a lot of calculations. I either have to
go back to the database and reselect everything based upon the overall
company (expensive in both time and resources) or add all of the department
data together in the program. If I could just declare a second view
based upon the summary of the first…
nauzad: looking at the scenerio u have described, you
have all your data in a DataSet... even if u wanted to create a view
from a view, it would stiff refer to the underlying DataTable and
regenerate the new view
nauzad: a view is nothing but a pointer to "selected rows"
in your DataTable
nauzad: its not like the rows in your view are stored
independently in some other location.
nauzad: so the end result (in terms of performance and
resources) would be the same even if you had the facility to create
a view from a view
nauzad: hope that answers your question
Deepak_MS: Ok friends, we are out of time for this week's chat...
if you do have any questions.. you can post them to your local user
group or India .NET forums..
nauzad: Thanks everyone for your time... have a nice weekend