I've been teaching Microsoft's 2-day .NET developer training seminar for the past 3 months, and have been putting a lot of thought into how ADO.NET compares to EJB 2.
My current thought is that ADO.NET strikes me as BeanManagedPersistence done correctly. It has a couple of features that sorta look like container managed persistence, but on closer look, they aren't the same thing.
ADO.NET has a DataSet and a DataAdapter class. The DataAdapter is a composition of the 4 SQL DML statements needed to read and manipulate data in a table (select, insert, update, delete), along with a TableMapping for easy-read display names to table/column names.The composition of the 4 SQL queries is identical to what one usually does with ejbFindByXXX/ejbStore/ejbCreate/ejbRemove. It doesn't have ejbLoad/ejbFindByPrimaryKey because it loads data in a set oriented manner.
The DataAdapter doesn't have the N+1 database call problem that EJB BMP has, mainly because the DataAdapter has full responsibility for mapping to fields (DataRows in DataColumns). The tradeoff was that we don't have hard-coded primitive fields, we have dynamic fields. Typed DataSets provide a hybrid approach because you can generate strongly typed fields, but they're still a specific kind of object in ADO.NET (i.e. DataColumn, DataTable). This pattern I would liken to PropertyContainer in IbmSanFrancisco or to the way an EOF object stores its data in WebObjects, though I would suggest WebObjects has the more elegant approach of dynamically figuring out where the data should go, in the dynamic container, or the hard coded field if it exists.
From a code simplicity perspective, ADO.NET has a CommandBuilder to simplify generation of SQL for naive optimistic concurrency (one assumes it will become more advanced in later versions). Visual Studio .NET Enterprise Developer's server explorer will allow you to drag a table into your project and it will generate the SQL & ADO.NET code for full-field optimistic concurrency conflict checking. This is pretty verbose stuff, almost as much as if you wrote your own DataAccessObject in JDBC or BeanManagedPersistence. To those who complain about the code generation involved with EJB, I'd point to this as my way of saying "these guys do it too".
From a ContainerManagedPersistence perspective, ADO.NET has DataRelations for traversing tables and Constraints for cascade delete.It also has change-tracking and in-memory rollback, something an EJB 2 CMP implementation typically has. But on my browsing, it doesn't have:
ADO.NET does have, however:
I must admit, I rarely use the DataTable/Row/Column model in my own code. I find it allows the relational model to bubble through many layers of an application, instead of hiding it. I just use the DataReader and Command.ExecuteXXX. <shrug>
ExecuteXXX is fine unless you have the need for a disconnected update model. I.e. a data cache of some sort, for example in a 2-tier C/S application. That's where DataSet shines -- not so much in web applications. --StuCharlton
Any idea what sort of performance hit you take by using TypedDataSets? in a real-world 2-3-tier web application? For passing between tiers (versus hand-coded data objects)
TypedDataSets? really just wrap type-casts around the code you'd normally use to access a DataSet. In my experience it's negligable between the two formats. Now, you're asking a second question -- should one use it for passing between tiers? Building an object graph of data really doesn't provide any benefits unless you start deriving data out of it or updating data within the graph. --Stu Apr04
I've been struggling with the issue of whether to use DataSets because of that "bubbling" issue. I haven't come to a firm conclusion yet, but I've found it helpful to consider MartinFowler's advice in his new book, Patterns of Enterprise Application Architecture. He writes,
"Looking at .NET, Visual Studio, and the history of application development in the Microsoft world, the dominant pattern is Table Module. Although object bigots tend to dismiss this as just meaning that Microsofties don't get objects, the Table Module does present a valuable compromise between Transaction Script and Domain Model, with an impressive set of tools that take advantage of the ubiquitous data set acting as a Record Set. ...
"This doesn't mean that you can't use Domain Model, indeed you can build a Domain Model just as easily in .NET as you can in any other OO environment. But the tools don't give you the extra help that they do for Table Modules, so I'd tolerate more complexity before I felt the need to shift to a Domain Model."
It strikes me as the usual good advice from Fowler. In my domain, I'm often dealing with sets of entities. It strikes me now as more work that it's worth to split such a set up into individual objects in one layer, only to recombine them in another. -- RobinEvans?
Microsoft have written an extensive article on this topic (when to use datasets versus "real" objects) here: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/BOAGag.asp
There is also some related material here: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/designnetapp.asp
--JohnRusk
Does anyone have any experience with the pre release of ObjectSpaces? --ShaunSmith
There was that really old version that I played with a bit circa 2002. It's changed significantly and there's a full release coming with VS.NET Whidbey this year. The demo at the PDC showed significant progress, though it's not quite yet at Hibernate or TOPLink levels of flexibility. --StuCharlton Apr04