2011-07-26 12 views
10

Estoy seguro de que hay una razón extremadamente simple de que esta línea no funciona, pero se ha evadido durante la última semana, así que espero que alguien más lo note mi culpa.DataAdapter.Update() no actualiza la base de datos

He estado trabajando en este proyecto durante varias semanas a un mes. He estado usando una mezcla de DataAdapter, CommandBuiler, etc. con una codificación de linq a sql en 1 base de datos, con múltiples formularios de aplicación de Windows. Esta forma particular edita o elimina filas de la base de datos usando DataAdapter, Dataset y Command Builder. Ha funcionado bien, hasta que cambié de computadora. Ahora el Dataset se está actualizando, pero la Base de datos no lo está.

Aquí está el código completo de este formulario:

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

Esto se supone para actualizar la tabla:

dataAdapt.Update(dataRecipe, "CookBookRecipes"); 

ahora no recibo ningún error, pero la tabla de datos acaba de ganar' t actualización.

Gracias de antemano por su ayuda, y solo hágamelo saber si necesita más información.

+0

¿Alguna vez recibió una respuesta al respecto? Estoy teniendo el mismo problema con un proyecto que construí para manejar mis actualizaciones de Db. Utilizándolo desde un proyecto, falla tal como lo nota. Utilizándolo de otro, funciona bien. Así que estoy realmente perplejo. Incluso he comparado el SqlAdapter.GetUpdateCommand(). CommandText de los dos y son exactamente los mismos que los elementos de datos de ItemArray. Aunque no entiendo todos los parámetros en el comando INSERT autogenerado. RowStates también son lo mismo. Frustrante. –

Respuesta

2

¿Cómo es el SqlCommand for Update? Veo el comando pero no veo ningún SqlText, eso es lo que te estás perdiendo.

es necesario definir lo que .Update hace mediante el establecimiento de .UpdateCommand propiedad en el SqlDataAdapter

Este enlace da una buena avería en la forma de hacerlo: http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldataadapter.updatecommand.aspx

+0

SqlText? ¿Dónde pondría eso? – Miffed

+0

Gracias. ¿Pero cómo usaría eso en mi código? – Miffed

11

Con el fin de actualizar los datos de la base de datos su SqlDataAdapter necesita tener sus propiedades InsertCommand, UpdateCommand, DeleteCommand establecidas. La instancia de SqlCommandBuilder que ha creado tiene estos comandos, pero debe configurarlos en su SqlDataAdapter.

En otros mundos: En algún lugar entre

SqlCommandBuilder cb; 
cb = new SqlCommandBuilder(dataAdapt); 

y

dataAdapt.Update(dataRecipe, "CookBookRecipes"); 

que necesita para

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

buscado por todas partes, y nadie mencionó el enlace de las consultas que el generador de comandos genera al adaptador de datos. Gracias por esto. – Ajibola

+1

Solo tenga en cuenta que si especifica el dataAdaptor al crear el SqlCommandBuilder NO necesita establecer los comandos, el SqlCommandBuilder se registra a sí mismo como un oyente. [Documentación] (https://msdn.microsoft.com/en-us/library/w0154tsb (v = vs.110) .aspx) – nicV

0

Es posible que tenga

DataAdapeter.AcceptChanges() 
0

Tuve el mismo problema: llené un nuevo conjunto de datos con algunas filas nuevas, pero no sucedió nada en la actualización. He usado MySqlDataAdapter, que funciona de manera similar.

Resulta que cuando necesita InsertCommand desde MySqlCommandBuilder, debe especificar el estado de los surcos como agregado. Consulte también: 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

Pruebe la fuente a continuación.

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

Adición AcceptChangesDuringUpdate antes de actualización funciona para mí, ejemplo:

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

me he encontrado con el mismo problema. Mi dataadapter.fill funciona pero dataadapter.update no funciona. Me di cuenta de que el problema era que mi tabla de base de datos no contiene una clave principal. Después de modificar mi tabla para incluir una columna con clave principal, dataadapter.fill funciona. Espero que esto ayude a alguien.

Cuestiones relacionadas