I started out using .NET and ADO.NET using almost exclusively DataReaders for reading data, and Stored Procedures for inserting/updating data. In general, I have found this to be scalable and entirely reasonable performance wise.
I have recently started using DataSets on occasion. My criteria for use is either that the content of the resulting dataset is reasonably static and can be cached, or if it needs to be used several times in a single request (for instance, a DataSet to be bound to several different Drop Down Lists or a DataSet where I will use a number of different views to feed a User Control). So, I use DataReaders in many cases, because much of the data I am using is not terribly static, and often something that is very user specific. Are people out there doing session-based caching of datasets?
I have started using IDataReader as the return value from any of my utility classes when returning a DataReader is required rather than returning a SqlDataReader. This in theory isolates the SQL Server specific stuff in my Data Access Layer, and I could change databases more reasonably (though in practice, it seems very unlikely any current projects would actually change databases). In addition, none of my applications are likely to need to place the Data Access Layer on a different physical machine, so the disconnectedness of a DataSet is not likely to be required.
Several recent books I have read (Pragmatic ADO.NET, for instance) seem to minimize the utility of the Data Reader. Other than the awkwardness of needing to verify that ExecuteReader() is called with the correct parameter and that I verify that I close the returned DataReader (and I am comfortable that I have a pattern in place that works reliably), am I missing something?
One of the most annoying parts of developing a database application is when the database does not do what you think it should. Often, it ends up that is because you are not telling it exactly what you think you are.
For those times, if you are a SQL Server user (or MSDE user with the client tools installed) you can use SQL Profiler. Briefly, SQL Profiler allows you to see a trace of what is actually being sent to the database. On more than one occasion, I discovered much to my horror that I in fact was not sending the parameter that I thought I was.
If you are a SQL Server user, familiarize yourself with SQL Profiler. It can be a lifesaver.