2011-07-26 22 views
10

Sono sicuro che esiste una ragione estremamente semplice per cui questa linea non funziona, ma è stata elusa per la settimana passata, quindi spero che qualcun altro se ne accorga colpa mia.DataAdapter.Update() non aggiorna il database

Ho lavorato a questo progetto per diverse settimane fino a un mese. Ho usato un mix di vecchi DataAdapter, CommandBuiler, ecc. Con alcuni codici da linq a sql su 1 database, con più moduli di domanda di Windows. Questo particolare modulo Modifica o elimina le righe dal database utilizzando un DataAdapter, Dataset e Command Builder. Ha funzionato bene, fino a quando ho acceso i computer. Ora il dataset viene aggiornato, ma il database no.

Ecco il codice completo di questa forma:

private void exitToolStripMenuItem_Click(object sender, EventArgs e) 
{ 
    if (MessageBox.Show("Exit Cook Book?", "Exit?", MessageBoxButtons.OKCancel) == DialogResult.OK) 
    { 
     Application.Exit(); 
    } 
} 

private void goBackToolStripMenuItem_Click(object sender, EventArgs e) 
{ 
    AddRecipe goBack = new AddRecipe(); 

    Close(); 
    goBack.Show(); 
} 

private void helpToolStripMenuItem_Click(object sender, EventArgs e) 
{ 
    MessageBox.Show("Scan through the Cook Book to find recipes that you wish to edit or delete.", "Help!"); 
} 

SqlConnection con; 
SqlDataAdapter dataAdapt; 
DataSet dataRecipe; 
SqlCommandBuilder cb; 

int MaxRows = 0; 
int inc = 0; 


private void EditRecipe_Load(object sender, EventArgs e) 
{ 
    con = new SqlConnection(); 
    dataRecipe = new DataSet(); 

    con.ConnectionString = "Data Source=.\\SQLEXPRESS;AttachDbFilename=|DataDirectory|\\Recipes.mdf;Integrated Security=True;User Instance=True"; 

     con.Open(); 

     //MessageBox.Show("Database Open"); 

     string sql = "SELECT* From CookBookRecipes"; 
     dataAdapt = new SqlDataAdapter(sql, con); 

     dataAdapt.Fill(dataRecipe, "CookBookRecipes"); 
     NavigateRecords(); 
     MaxRows = dataRecipe.Tables["CookBookRecipes"].Rows.Count; 

     con.Close(); 
} 


private void NavigateRecords() 
{ 
    DataRow dRow = dataRecipe.Tables["CookBookRecipes"].Rows[inc]; 

    tbRName.Text = dRow.ItemArray.GetValue(0).ToString(); 
    listBox1.SelectedItem = dRow.ItemArray.GetValue(1).ToString(); 
    tbRCreate.Text = dRow.ItemArray.GetValue(2).ToString(); 
    tbRIngredient.Text = dRow.ItemArray.GetValue(3).ToString(); 
    tbRPrep.Text = dRow.ItemArray.GetValue(4).ToString(); 
    tbRCook.Text = dRow.ItemArray.GetValue(5).ToString(); 
    tbRDirections.Text = dRow.ItemArray.GetValue(6).ToString(); 
    tbRYield.Text = dRow.ItemArray.GetValue(7).ToString(); 
    textBox1.Text = dRow.ItemArray.GetValue(8).ToString(); 
} 

private void btnNext_Click(object sender, EventArgs e) 
{ 
    if (inc != MaxRows - 1) 
    { 
     inc++; 
     NavigateRecords(); 
    } 
    else 
    { 
     MessageBox.Show("That's the last recipe of your Cook Book!", "End"); 
    } 
} 

private void btnBack_Click(object sender, EventArgs e) 
{ 
    if (inc > 0) 
    { 
     inc--; 
     NavigateRecords(); 
    } 
    else 
    { 
     MessageBox.Show("This is the first recipe of your Cook Book!", "Start"); 
    } 
} 

private void btnSave_Click(object sender, EventArgs e) 
{ 
    cb = new SqlCommandBuilder(dataAdapt); 

    DataRow daRow = dataRecipe.Tables["CookBookRecipes"].Rows[inc]; 

    daRow[0] = tbRName.Text; 
    daRow[1] = listBox1.SelectedItem.ToString(); 
    daRow[2] = tbRCreate.Text; 
    daRow[3] = tbRIngredient.Text; 
    daRow[4] = tbRPrep.Text; 
    daRow[5] = tbRCook.Text; 
    daRow[6] = tbRDirections.Text; 
    daRow[7] = tbRYield.Text; 
    daRow[8] = textBox1.Text; 

    if (MessageBox.Show("You wish to save your updates?", "Save Updates?", MessageBoxButtons.OKCancel) == DialogResult.OK) 
    { 

     dataAdapt.Update(dataRecipe, "CookBookRecipes"); 

     MessageBox.Show("Recipe Updated", "Update"); 
    } 
} 

private void btnDelete_Click(object sender, EventArgs e) 
{ 
    SqlCommandBuilder cb; 
    cb = new SqlCommandBuilder(dataAdapt); 

    if (MessageBox.Show("You wish to DELETE this recipe?", "Delete?", MessageBoxButtons.OKCancel) == DialogResult.OK) 
    { 
     dataRecipe.Tables["CookBookRecipes"].Rows[inc].Delete(); 
     MaxRows--; 
     inc = 0; 
     NavigateRecords(); 

     dataAdapt.Update(dataRecipe, "CookBookRecipes"); 

     MessageBox.Show("Your Recipe has been Deleted", "Delete"); 
    } 
} 

Questo dovrebbe aggiornare la tabella:

dataAdapt.Update(dataRecipe, "CookBookRecipes"); 

Non ricevo gli eventuali errori, ma la tabella dei dati appena vinto' t aggiornamento.

Grazie in anticipo per il vostro aiuto, e fammi sapere se avete bisogno di ulteriori informazioni.

+0

Hai mai ricevuto una risposta? Sto avendo lo stesso problema con un progetto che ho creato per gestire i miei aggiornamenti Db. Usandolo da un progetto, fallisce proprio come si nota. Usandolo da un altro, funziona bene. Quindi sono davvero perplesso. Ho persino confrontato SqlAdapter.GetUpdateCommand(). CommandText tra i due e sono esattamente gli stessi degli elementi di dati ItemArray. Tuttavia, non capisco tutti i parametri nel comando INSERT generato automaticamente. I RowState sono uguali. Frustrante. –

risposta

2

Che aspetto ha l'SqlCommand per l'aggiornamento? Vedo il comando ma non vedo alcun SqlText, questo è quello che ti manca.

è necessario definire cosa .Update fa impostando .UpdateCommand proprietà sul SqlDataAdapter

Questo link dà un buon ripartizione su come andare a questo proposito: http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldataadapter.updatecommand.aspx

+0

SqlText? Dove lo metterei? – Miffed

+0

Grazie. Ma come lo userei nel mio codice? – Miffed

11

Al fine di aggiornare i dati sulla database il tuo SqlDataAdapter deve avere le sue proprietà InsertCommand, UpdateCommand, DeleteCommand. L'istanza di SqlCommandBuilder che hai creato ha questi comandi, ma devi impostarli su SqlDataAdapter.

In altri mondi: Da qualche parte tra

SqlCommandBuilder cb; 
cb = new SqlCommandBuilder(dataAdapt); 

e

dataAdapt.Update(dataRecipe, "CookBookRecipes"); 

è necessario

dataAdapt.DeleteCommand = cb.GetDeleteCommand(true); 
dataAdapt.UpdateCommand = cb.GetUpdateCommand(true); 
dataAdapt.InsertCommand = cb.GetInsertCommand(true); 
+2

ha cercato dappertutto e nessuno ha menzionato l'associazione delle query che il generatore di comandi genera all'adattatore dati. Grazie per questo. – Ajibola

+1

Solo una nota che se si specifica dataAdaptor durante la creazione di SqlCommandBuilder NON è necessario impostare i comandi, SqlCommandBuilder si registra come listener. [Documentation] (https://msdn.microsoft.com/en-us/library/w0154tsb (v = vs.110) .aspx) – nicV

0

Potrebbe essere necessario

DataAdapeter.AcceptChanges() 
0

Ho avuto lo stesso problema: riempito un nuovo dataset con alcune nuove righe, ma non è successo nulla durante l'aggiornamento. Ho usato MySqlDataAdapter che funziona in modo simile.

Si scopre che quando hai bisogno di InsertCommand da MySqlCommandBuilder devi specificare lo stato della riga come aggiunto. Vedi anche: MSDN

0
//change this line 

DataRow daRow = dataRecipe.Tables["CookBookRecipes"].NewRow(); 

daRow[0] = tbRName.Text; 
daRow[1] = listBox1.SelectedItem.ToString(); 
daRow[2] = tbRCreate.Text; 
daRow[3] = tbRIngredient.Text; 
daRow[4] = tbRPrep.Text; 
daRow[5] = tbRCook.Text; 
daRow[6] = tbRDirections.Text; 
daRow[7] = tbRYield.Text; 
daRow[8] = textBox1.Text; 

if (MessageBox.Show("You wish to save your updates?", "Save Updates?", MessageBoxButtons.OKCancel) == DialogResult.OK) 
{ 
//add & change this too 
dataRecipe.Tables["CookBookRecipes"].Rows.Add(daRow); 
    dataAdapt.Update(dataRecipe, "CookBookRecipes"); 

    MessageBox.Show("Recipe Updated", "Update"); 
} 

}

0

provare la fonte qui sotto.

private void btnSave_Click(object sender, EventArgs e) 
{ 
    cb = new SqlCommandBuilder(dataAdapt); 

    //Old source: DataRow daRow = dataRecipe.Tables["CookBookRecipes"].Rows[inc]; 

    //Added source code 
    DataRow daRow = dataRecipe.Tables["CookBookRecipes"].NewRow(); 

    //Added source code 
    dataRecipe.Tables["CookBookRecipes"].AddRow(daRow); 

    daRow.BeginEdit(); 
    daRow[0] = tbRName.Text; 
    daRow[1] = listBox1.SelectedItem.ToString(); 
    daRow[2] = tbRCreate.Text; 
    daRow[3] = tbRIngredient.Text; 
    daRow[4] = tbRPrep.Text; 
    daRow[5] = tbRCook.Text; 
    daRow[6] = tbRDirections.Text; 
    daRow[7] = tbRYield.Text; 
    daRow[8] = textBox1.Text; 
    daRow.EndEdit(); 

    //Reset state of rows to unchanged 
    dataRecipe.Tables["CookBookRecipes"].AcceptChanges(); 
    //Set modified. The dataAdapt will call update stored procedured 
    //for the row that has Modifed row state. 
    //You can also try SetAdded() method for new row you want to insert 
    daRow.SetModified(); 

    if (MessageBox.Show("You wish to save your updates?", "Save Updates?", MessageBoxButtons.OKCancel) == DialogResult.OK) 
    { 

     dataAdapt.Update(dataRecipe, "CookBookRecipes"); 

     MessageBox.Show("Recipe Updated", "Update"); 
    } 
} 
0

Aggiunta AcceptChangesDuringUpdate prima di aggiornamento funziona per me, ad esempio:

foreach (string tableName in tableNames) 
     {    
      da = new SqlDataAdapter("SELECT * FROM " + tableName, cn); 
      cb = new SqlCommandBuilder(da); //initialise the update, insert and delete commands of da 
      da.AcceptChangesDuringUpdate = true; 
      da.Update(myDataSet, tableName);    
     } 
0

ho incontrato lo stesso problema. Il mio dataadapter.fill funziona ma dataadapter.update non funziona. Mi sono reso conto che il problema era che la mia tabella di database non contiene una chiave primaria. Dopo aver modificato la mia tabella per includere una colonna con chiave primaria, dataadapter.fill funziona. Spero che questo aiuti qualcuno.