<<I read a couple of your articles and one item caught my attention. If I
interpret correctly, you mentioned that since a DataSet is an approximation
of your database, then only one DataSet per application is needed. >> As a
general rule, Yes, this is correct. I see wayyyy too much code with
multiple datasets and no apparent reason for this. I think a lot of code
examples use datasets and datatables interchangeably and many examples use
datasets even if there is only one table in the dataset, so many get the
impression that they are interchangeable. While they are in many regards
(you can bind a Grid for example to a datatable or a dataset and if you bind
it to a one table dataset, the result is indistinguishable between the two),
remember that they are different objects. A DataSet is essentially a
collection of DataTables. If you create a DataSEt with one table, remember
that you've created Two objects, not one. If all the functionality you need
can be handled with just one, it's inefficient to do this (However, if you
need the functionality or have a good reason, then don't worry about it.
Just make sure the benefit is worth the cost).
Anyway, there are instances when you may need more than one dataset or it
logically makes sense to have more than one... after all, there are many
times when you have more than one named instance of a server that you use in
a project b/c your company splits its data for whatever reason (your HR
Application runs on Oracle, your CRM runs on SQL Server, etc).
<<Where would you instantiate the DataSet? >> It really depends on the
app... some of my apps only have one or two forms, others have hundreds.
You basically have two choices.
The first and easiest is to create a class that's sealed, with all static
members and is a single instance class. You can implement a singleton
pattern or you can just have a class with all static properties and methods.
One of the properties will be A dataset. You could just use this one
property to reference your tables or you could create another property for a
table or tables and then in your get accessor, do something like this inside
the class
public static DataTable Customers{
get{return this.ProjectDataSet.Tables["Customers'];}
}
outside the class you'd get at it like, foreach(DataRow dro in
mySharedClass.Customers.Rows){
}
Or, you could not use a property for the tables(s) and just do this
foreach(DataRow dro in mySharedClass.ProjectDataSet.Tables["Customers"]){
}
They are the same thing, it's just one way lets you access the tables
directly and is ostensibly more 'object oriented' YOu could also use this
class to return aggregetes with DataTable.Compute, or filtering with
DataView.Rowfilter ---- I've written on this extensively at
www.knowdotnet.com under William Ryan or DataAccess (Efficiently Using
ADO.NET 1,2 & 3 and any of my DataView articles)
You can also declare it wherever and just pass it around or use it to set
the properties of your business objects, then have the business objects do
their thing and when they return, modify the dataset accordingly. The
architecture plays a big role here but this is definitely one viable way.
SO maybe you call a web service or your DataAccess layer and fill the
dataset at the beginning. It's instantiated in your Main form. THen you use
it to populate some business objects, pass the business objects around and
when all is said and done, take them and fill/add/delte/change stuff in your
dataset. Rocky Lhotka has a book on Business Objects in VB.NET or C# (I
forget the name) where he uses an approach something like this (although I'm
not doing it justice b/c it's much more clever than the briefl little piece
I described>
As far as DataAdapters, doesn't really matter. Remember that you give them
a Select, Update, Delete and INsert command, and they do the rest. All
they ne3ed is a datatable, then they look at the Rowstate and make a
determination, one row at a time, which command to call against each row
based on its state. So you can fill a dataset with a dataadapter in Form1,
then have a another dataadapter in some dataaccess.dll that has the same
commands, change the values in your datatables, and call update with the
adapter from the .dll and provided they had the same update/insert/etc
commands, the behavior would be identical. Adapaters don't care where the
data came from...as long as they have their commands and those commands
match the table they are updating, all is well. But you'd probably want to
keep your adapters in a similar place, in a dataaccess class that you can
get to from anywhere (but, since they don't need to preserve their state
like DataSet/datatables do, it doesn't matter if you instantiate a new
instance (from a dataaccess point of view...from an efficiency point of
view, you don't want to just create new adapters willy nilly - or any other
object for that matter). Remember the #1 thing... DataSets/dataTables have
to know the Rowstate of their rows to be of much use in update scenarios.
So preserving state is crucial. As such, one instance, (shared in VB.NET,
static in C#) visible from everywhere is what you are after in this case.
DataAdapters don't need state or care about thier own, only about the state
of the rows of the table they are asked to update. (provided they have valid
commands).
Does that help? IF not, let me know and I'll elaborate more...