2012-07-05 10 views
15

Próbuję wypełnić DataSet, który zawiera 2 tabele z jednym do wielu relacji. Używam DataReader do osiągnięcia tego celu:Jak wypełnić zestaw danych wieloma tabelami?

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; 
    } 

Ale mam tylko jeden stół wypełniony. Jak osiągnąć mój cel - wypełnić obie tabele?

Chciałbym użyć DataReader zamiast DataAdapter, jeśli to możliwe.

+3

Dlaczego można się spodziewać, że dwa stoły są wypełnione? Twoje polecenie zawiera tylko jedną instrukcję 'select', która zwraca pojedynczą tabelę. –

+2

Dlaczego nie użyć 'SqlDataAdapter' i jego metody' Fill (...) 'zamiast' DbCommand'? – bluevector

+0

@Nikola Anusev - Znam to, więc pytam o jakąkolwiek propozycję –

Odpowiedz

19

Jeśli wystawienie jednego polecenia z kilku wybranych stwierdzeń, można użyć metody NextResult, aby przejść do następnego wynikowego w datareader: http://msdn.microsoft.com/en-us/library/system.data.idatareader.nextresult.aspx

mi pokazać, jak to mogło wyglądać poniżej:

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

Możesz po prostu zrobić 'result.Load (reader)'. Metoda 'Load' będzie obsługiwać wiele zestawów wyników. – AMissico

+0

@ Amissico, prawda, ale która tabela do wypełnienia której zestaw wyników nie może być jawnie podana przy pomocy DataSet.Load, zostanie złamana, jeśli zdefiniujesz tabele w innej kolejności. Musisz również podać inne parametry. – smoothdeveloper

+0

kazałeś mi się uśmiechnąć dzisiaj. – AMissico

23

Wypełnienie Wi DataSet wiele tabel można wykonać, wysyłając wiele żądań do bazy danych lub w szybszy sposób: wiele instrukcji SELECT można wysłać do serwera bazy danych w jednym żądaniu. Problem polega na tym, że tabele generowane z zapytań mają automatyczne nazwy Table i Table1. Jednak wygenerowane nazwy tabel można odwzorować na nazwy, które powinny być używane w zestawie danych.

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

Dziękuję za odpowiedź, ale zgodnie z moim zadaniem - muszę użyć DataReader zamiast DataAdapter: to było opisane w moim pytaniu –

+3

dodawanie z TableMappings.Add nie jest neccassarry –

7

Jest to stary temat, ale dla niektórych ludzi może to być przydatne:

 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

jak radzić sobie z tą sytuacją, jeśli sql (store proc) zwracając wiele tabel ? –

+1

Zamiast robić 'adapt.Fill (someDataSet.Tables [" Table1 "])' zrobiłbyś 'adapt.Fill (someDataSet)'. Ze względu na to, że procedura składowana powoduje ponowne generowanie tabel, ale tylko wtedy, gdy rzeczywiście zwraca TABELE, a nie zbiór KOLUMNY z wielu tabel. – CularBytes

+0

Dzięki za odpowiedź, spróbuję tego :-) –

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

Proszę, dodaj wyjaśnienie. – gofr1

Powiązane problemy