I'll take your points one by one. I hope its ok! Make sure to tell me if I missed anything.
ow, formerly we would use stored procedures for all the queries and
gather everything for class files up the chain, however, with typed
datasets, are stored procedures necessary, or is it enough to let the
typed dataset generate the sql code for the fill and simply do all your
queries and data aggregation through the returned datatable using
dataviews?
The whole "everything in stored procs" ideology had roots in 10 years old technology. Its over now. With client/server apps, SOA, or web apps, your clients are never directly accessing the database, so it makes stored procs redundant. SQL Server also handles stored procs the same it does sql queries (go ahead and use a benchmark tools, you'll be surprised) so speed isn't an issue anymore. In Java, between enterprise javabeans persistance layers and ORMs like Hibernate, stored procs haven't been standard in a while. in the Microsoft world its getting there, and things like LINQ will give the final blow. There is a place and time for stored procedures, but starting with the idea that stored procs is the "default" is a bad one: When you have 150-300 tables, your CRUD operations alone would take over a thousand procs: crazy! How do you manage that @.@
So yes, using queries directly in your datasets is a fine DAL. Since your dataset is an in memory replication of your database anyway, it would make things redundant. (I have to deal with stored procs for work now...and ugh, management nightmare!)
The next tier would be my data access layer
No. Your dataset itself is the DAL. The next step is the Business layer. Is that what you meant? Your code starts with BLL in it afterward.
Ok, here is a potential suggestion for your caching issues afterward:
Assuming your datasets is your DAL. Then you make a BLL on top of that, that will allow you to do various operations, including a layer over your CRUD operations. So far so good. Now, one thing thats nice with .NET 2, is you have access to Object Data Source. Which allows you to map CRUD to business objects.
So what you do, is after you have your BLL, you build lightweight "CRUD" objects at the level of your presentation layer (in app_code). Then use an Object Data Source, which will see your objects in app_code, and you can map your operations to it. Then you can use databinding in your presentation layer, while keeping your architecture. Whats nice though, is that ObjectDataSource has an internal Caching feature (look in its properties, its actualy quite powerful), thus you won't have to deal with it yourself. That could save you some time, while still cleanly separating your layers.
Otherwise, if you stick your datasets in Session everytime, you will totally overload your server (they take a lot of memory).
If that doesn't do the trick, look into the Cache object. It has features to handle caching, including cache dependencies to SQL Server 2005 (so if a table change, cache is automatically refreshed, etc).