2012-07-05 3 views
15

Sto cercando di riempire DataSet che contiene 2 tabelle con una relazione uno a molti. Sto usando DataReader per raggiungere questo obiettivo:Come riempire il set di dati con più tabelle?

public DataSet SelectOne(int id) 
    { 
     DataSet result = new DataSet(); 
     using (DbCommand command = Connection.CreateCommand()) 
     { 
      command.CommandText = "select * from table1"; 

      var param = ParametersBuilder.CreateByKey(command, "ID", id, null); 
      command.Parameters.Add(param); 

      Connection.Open(); 
      using (DbDataReader reader = command.ExecuteReader()) 
      { 
       result.MainTable.Load(reader); 
      } 
      Connection.Close(); 
     } 
     return result; 
    } 

ma ho solo una tabella riempito. Come raggiungo il mio obiettivo: riempire entrambi i tavoli?

Vorrei usare DataReader invece DataAdapter, se possibile.

+3

Perché si aspetterebbe che due tabelle sono pieni? Il tuo comando contiene solo una singola istruzione 'select' che restituisce una singola tabella. –

+2

Perché non utilizzare 'SqlDataAdapter' e il suo metodo' Fill (...) 'invece di' DbCommand'? – bluevector

+0

@Nikola Anusev - Lo so, quindi sto solo chiedendo qualsiasi tipo di suggerimento –

risposta

19

Se l'emissione di un singolo comando con più istruzioni SELECT, si potrebbe utilizzare il metodo NextResult per passare al successivo gruppo di risultati all'interno del datareader: http://msdn.microsoft.com/en-us/library/system.data.idatareader.nextresult.aspx

faccio vedere come potrebbe apparire sotto:

public DataSet SelectOne(int id) 
{ 
    DataSet result = new DataSet(); 
    using (DbCommand command = Connection.CreateCommand()) 
    { 
     command.CommandText = @" 
select * from table1 
select * from table2 
     "; 

     var param = ParametersBuilder.CreateByKey(command, "ID", id, null); 
     command.Parameters.Add(param); 

     Connection.Open(); 
     using (DbDataReader reader = command.ExecuteReader()) 
     { 
      result.MainTable.Load(reader); 
      reader.NextResult(); 
      result.SecondTable.Load(reader); 
      // ... 
     } 
     Connection.Close(); 
    } 
    return result; 
} 
+7

Si può semplicemente eseguire 'result.Load (reader)'. Il metodo 'Load' gestirà più set di risultati. – AMissico

+0

@AMissico, true ma la tabella da compilare con quale set di risultati non può essere esplicitamente dichiarata con DataSet.Load, si interromperà se si definiscono le tabelle in un altro ordine. Inoltre devi specificare altri parametri. – smoothdeveloper

+0

mi hai fatto sorridere oggi. – AMissico

23

Riempire un DataSet wi È possibile eseguire più tabelle inviando più richieste al database o in modo più rapido: più istruzioni SELECT possono essere inviate al server di database in una singola richiesta. Il problema qui è che le tabelle generate dalle query hanno nomi automatici Tabella e Tabella1. Tuttavia, i nomi delle tabelle generate possono essere associati a nomi che dovrebbero essere utilizzati nel DataSet.

SqlDataAdapter adapter = new SqlDataAdapter(
     "SELECT * FROM Customers; SELECT * FROM Orders", connection); 
adapter.TableMappings.Add("Table", "Customer"); 
adapter.TableMappings.Add("Table1", "Order"); 

adapter.Fill(ds); 
+0

Grazie per la risposta, ma secondo il mio compito - Ho bisogno di usare DataReader invece DataAdapter: è stato descritto nella mia domanda –

+3

aggiungendo con TableMappings.Add non è neccassarry –

7

Si tratta di un argomento vecchio, ma per alcune persone potrebbe essere utile:

 DataSet someDataSet = new DataSet(); 
     SqlDataAdapter adapt = new SqlDataAdapter(); 

     using(SqlConnection connection = new SqlConnection(ConnString)) 
     { 
      connection.Open(); 
      SqlCommand comm1 = new SqlCommand("SELECT * FROM whateverTable", connection); 
      SqlCommand comm2g = new SqlCommand("SELECT * FROM whateverTable WHERE condition = @0", connection); 
      commProcessing.Parameters.AddWithValue("@0", "value"); 
      someDataSet.Tables.Add("Table1"); 
      someDataSet.Tables.Add("Table2"); 

      adapt.SelectCommand = comm1; 
      adapt.Fill(someDataSet.Tables["Table1"]); 
      adapt.SelectCommand = comm2; 
      adapt.Fill(someDataSet.Tables["Table2"]); 
     } 
+0

come può gestire questa situazione, se sql (store proc) restituisce più tabelle ? –

+1

Invece di fare 'adapt.Fill (someDataSet.Tables [" Table1 "])' si farebbe 'adapt.Fill (someDataSet)'. A causa del corso, la procedura memorizzata esegue di nuovo le tabelle, ma solo se restituisce realmente TABELLE e non un set di COLONNE da più tabelle. – CularBytes

+0

Grazie per la risposta, proverò questa cosa :-) –

0
protected void Page_Load(object sender, EventArgs e) 
{ 
    SqlConnection con = new SqlConnection("data source=.;uid=sa;pwd=123;database=shop"); 
    //SqlCommand cmd = new SqlCommand("select * from tblemployees", con); 
    //SqlCommand cmd1 = new SqlCommand("select * from tblproducts", con); 
    //SqlDataAdapter da = new SqlDataAdapter(); 

    //DataSet ds = new DataSet(); 
    //ds.Tables.Add("emp"); 
    //ds.Tables.Add("products"); 
    //da.SelectCommand = cmd; 
    //da.Fill(ds.Tables["emp"]); 
    //da.SelectCommand = cmd1; 

    //da.Fill(ds.Tables["products"]); 
    SqlDataAdapter da = new SqlDataAdapter("select * from tblemployees", con); 
    DataSet ds = new DataSet(); 
    da.Fill(ds, "em"); 
    da = new SqlDataAdapter("select * from tblproducts", con); 
    da.Fill(ds, "prod"); 

    GridView1.DataSource = ds.Tables["em"]; 
    GridView1.DataBind(); 
    GridView2.DataSource = ds.Tables["prod"]; 
    GridView2.DataBind(); 
} 
+0

Per favore, aggiungi qualche spiegazione. – gofr1