So you want to build your own entity objects? Maybe you are even
purchasing or authoring a code-gen tool to do it for you. I like to use
Datasets when possible and people ask why I like them so much. To be
fair, I'll write a list of reasons to not use datasets and create your
own entities - but for now, this post is all about the pros of datasets.
I've been on a two week sales pitch for DataSets with a client so let
me summarize.
- They are very bindable.
This is less of an issue for Web forms
which don't support 2 way databinding. But for Win forms, datasets are a
no brainer. Before you go and say that custom classes are just as
bindable and could be, go try an example of implementing IListSource,
IList, IBindingList and IEditableObject. Yes you can make your own
custom class just as bindable if you want to work at it.
- Easy persistence.
This is a huge one. Firstly, the DataAdapter is
almost as important as the DataSet itself. You have full control over
the Select, Insert, Update and Delete sql and can use procs if you like.
There are flavours for each database. There is a mappings collection
that can isolate you from changes in names in your database. But that's
not all that is required for persistence. What about optimistic
concurrency? The DataSet takes care of remembering the original values
of columns so you can use that information in your where clause to look
for the record in the same state as when you retrieved it. But wait,
there's more. Keeping track of the Row State so you know whether you
have to issue deletes, inserts, or updates against that data. These are
all things that you'd likely have to do in your own custom class.
- They are sortable.
The DataView makes sorting DataTables very easy.
- They are filterable.
DataView to the rescue here as well. In addition to filtering on column value conditions - you can also filter on row states.
- Strongly Typed Datasets defined by XSD's.
Your own custom classes
would probably be strongly typed too...but would they be code generated
out of an XSD file? I've seen some strongly typed collection generators
that use an XML file but that's not really the right type of document
to define schema with.
- Excellent XML integration.
DataSets provide built in XML
Serialization with the ReadXml and WriteXml methods. Not surprising, the
XML conforms to the schema defined by the XSD file (if we are talking
about a strongly typed dataset). You can also stipulate whether columns
should be attributes or elements and whether related tables should be
nested or not. This all becomes really nice when you start integrating
with 3rd party (or 1st party) tools such as BizTalk or InfoPath. And
finally, you can of course return a DataSet from a Web Service and the
data is serialized with XML automatically.
- Computed Columns
You can add your own columns to a DataTable that
are computed based on other values. This can even be a lookup on
another DataTable or an aggregate of a child table.
- Relations
Speaking of child tables, yes, you can have complex
DataSets with multiple tables in a master detail hierarchy. This is
pretty helpful in a number of ways. Both programmatically and visually
through binding, you can navigate the relationship from a single record
in master table to a collection of child rows related to that parent.
You can also enforce the the referential integrity between the two
without having to run to the database. You can also insert rows into the
child based on the context of the parent record so that the primary key
is migrated down into the foreign key columns of the child
automatically.
- Data Validation
DataSets help with this although it's not
typically thought of as an important feature. It is though. Simple
validations can be done by the DataSet itself. Some simple checks
include: Data Type, Not Null, Max Length, Referential Integrity,
Uniqueness. The DataSet also provides an event model for column changing
and row changing (adding & deleting) so you can trap these events
and prevent data from getting into the DataSet programmatically. Finally
with the SetRowError and SetColumnError you can mark elements in the
DataSet with an error condition that is can be queried or shown through
binding with the ErrorProvider. You can do this to your own custom
entities with implementation of the IDataErrorInfo interface.
- AutoIncrementing values
Useful for columns mapped to identity columns or otherwise sequential values.
This is not an exhaustive list but I'm already exhausted. In a future
post, I'll make a case for custom entities and not DataSets, but I can
tell you right now that it will be a smaller list.