Thanks for the post!

As has been observed, this can be achieved using TableMappings, for example, the following code writes out the table names "Customers" and "Orders":

SqlConnection sqlConn = new SqlConnection(connString);
SqlDataAdapter sqlAdapter = 
   new SqlDataAdapter("SELECT * FROM Customers;SELECT * FROM Orders", sqlConn);
sqlAdapter.TableMappings.Add("Table","Customers");
sqlAdapter.TableMappings.Add("Table1","Orders");

DataSet ds = new DataSet();
sqlAdapter.Fill(ds);
foreach(DataTable t in ds.Tables)
   Console.WriteLine(t.TableName);

Alternatively, in ADO.NET 2.0 we added a Load() command that allows you to directly load a datatable or dataset from any datareader, without requiring you to create a DataAdapter.  The Load() command does take an optional string of tablenames, so you could write the code as follows:

SqlConnection sqlConn = new SqlConnection(connString);
DataSet ds2 = new DataSet();
SqlCommand command = 
            new SqlCommand("SELECT * FROM Customers;SELECT * FROM Orders",sqlConn);
sqlConn.Open();
SqlDataReader reader = command.ExecuteReader;(CommandBehavior.CloseConnection);
ds2.Load(reader,LoadOption.OverwriteChanges,"Customers2","Orders2");
foreach(DataTable t in ds2.Tables)
   Console.WriteLine(t.TableName);

Given this direct mechanism, and a desire to avoid having too many overloads, we decided not to add another variation of overloads to Fill.

We could certainly revisit this decision if people feel this scenario is common/important enough to justify additional overloads, but our general feeling was that having too many overloads made the API more confusing.