Seite 1 von 2

MySqlDataAdapter aktualisiert nur manchmal.

Verfasst: Fr Aug 01, 2014 5:26 pm
von canlot
Hallo Freunde. Ich habe im Rahmen eines Projekts angefangen ein wenig mit Datagridview und den zugehörigen Komponenten zu spielen.
Am einfachsten scheint mir, ein SqlDataAdapter zu verwenden in meinen Fall ein MysqlDataAdapter.
Ich gebe die Daten an eine DataTable weiter mit der Methode Fill(). Mit der Methode Update() kann ich die Datensätze die ich in der DataTable geändert habe mit MySqlDataAdapter in der Datenbank aktualisieren sei es es sind neue Daten hinzugekommen oder gelöscht/geändert worden. Die Methode Update scheint aber nicht immer zu funktionieren, je nach Lust und Laune denke ich, denn ich konnte keinen Zusammenhang für die Änderung die ich am Code vorgenommen habe feststellen.

Klasse DbOp

Code: Alles auswählen

using System;
using MySql.Data.MySqlClient;
using System.Data;

namespace database
{
	/// <summary>
	/// Description of DbOp.
	/// </summary>
	public class DbOp
	{
		private string table;
		private MySqlConnection con;
		private string login = 
				"SERVER=localhost;" +
				"DATABASE=test;" +
				"UID=root;" +
				"Password=;";
		private MySqlDataAdapter adapter;
		private string opString = "select * from test";
		
		public DbOp(string table_name)
		{
			table = table_name;
			con = new MySqlConnection(login);
			adapter = new MySqlDataAdapter(opString, con);
			initCommands();
		}
		public void Fill(ref DataTable tabelle)
		{
			adapter.Fill(tabelle);
		}
		public void Update(ref DataTable tabelle)
		{
			adapter.Update(tabelle);
			
		}
		private void initCommands()
		{
			adapter.InsertCommand = new MySqlCommand("Insert into test(id, name) values(@id, @name)", con);
			adapter.InsertCommand.Parameters.Add("@id", MySqlDbType.Int32);
			adapter.InsertCommand.Parameters.Add("@name", MySqlDbType.Text, 65535, "name");
		}
		
	}
}
ja ich weiß der Argument im Construktor wird nicht benutzt(noch nicht) :D

MainForm

Code: Alles auswählen

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using MySql.Data.MySqlClient;
using System.Data;


namespace database
{
	/// <summary>
	/// Description of MainForm.
	/// </summary>
	public partial class MainForm : Form
	{
		DbOp operation;
		DataTable tabelle = new DataTable();
		public MainForm()
		{
			//
			// The InitializeComponent() call is required for Windows Forms designer support.
			//
			InitializeComponent();
			
			//
			// TODO: Add constructor code after the InitializeComponent() call.
			//
			operation = new DbOp("test");
			operation.Fill(ref tabelle);
			dataGridView1.DataSource = tabelle;
			dataGridView1.Columns["id"].ReadOnly = true;
		}
		
		void DataGridView1UserAddedRow(object sender, DataGridViewRowEventArgs e)
		{
			
		}
		
		void DataGridView1CellEndEdit(object sender, DataGridViewCellEventArgs e)
		{
			operation.Update(ref tabelle);
		}
	}
}

Re: MySqlDataAdapter aktualisiert nur manchmal.

Verfasst: Fr Aug 01, 2014 7:17 pm
von cloidnerux
Hast du dir mal die Beschreibung zu DataAdapter.Update durchgelesen:
http://msdn.microsoft.com/de-de/library ... .110).aspx?

Und was erwartest, was passiert?

Re: MySqlDataAdapter aktualisiert nur manchmal.

Verfasst: Fr Aug 01, 2014 10:20 pm
von canlot
JA, habe ich!
Was ich erwarte?
Ich erwarte dass ein Datensatz hinzugefügt wird nachdem ich eine Zelle bearbeitet habe, das passiert auch nur nicht immer. Ich habe keine Anhängigkeiten feststellen können zwischen meinen "Einfügeverhalten" und den Eintrag in die Datenbank.
Also Quasi:

Erwartung:
Datensatz wird eingefügt in die Datenbank, durch meine definierte Insertquery.

Tatsache bzw. Ergebnis:
Datensatz wird nicht immer in die Datenbank eingefügt, dass der DataAdapter also nicht immer aktualisiert.

Re: MySqlDataAdapter aktualisiert nur manchmal.

Verfasst: Sa Aug 02, 2014 10:17 am
von canlot
Könnte es ein Bug seitens Mysql-Connector sein?

Re: MySqlDataAdapter aktualisiert nur manchmal.

Verfasst: Sa Aug 02, 2014 6:39 pm
von canlot
Keiner ein Vorschlag oder eine Vermutung?

Re: MySqlDataAdapter aktualisiert nur manchmal.

Verfasst: So Aug 03, 2014 6:34 pm
von canlot
Ich habe gerade ein wenig herumexperimentiert und rausgefunden das Datagridview ein bisschen buggy ist.
Wenn der Ereignis ausgelöst wird also z.B. eine Zeile hinzugefügt wird, werden die grade hinzugefügten Daten noch nicht in den Bestand der DatagridView übernommen sondern erst beim nächsten Mal wenn eine andere neue Zeile hinzugefügt wird.
z.B. beim Ereignis -> DataGridView1CellValueChanged

das funktioniert:

Code: Alles auswählen

dataGridView1.Rows[dataGridView1.CurrentRow.Index].Cells["name"].Value.ToString()
das nicht:

Code: Alles auswählen

dataGridView1.Rows[dataGridView1.CurrentRow.Index].Cells["name"].Value.ToString()
da kommt ein Null Error:

Code: Alles auswählen

************** Exception Text **************
System.NullReferenceException: Object reference not set to an instance of an object.
   at database.MainForm.DataGridView1CellValueChanged(Object sender, DataGridViewCellEventArgs e) in c:\Users\Jakob\Documents\SharpDevelop Projects\database\database\MainForm.cs:line 56
   at System.Windows.Forms.DataGridView.OnCellValueChanged(DataGridViewCellEventArgs e)
   at System.Windows.Forms.DataGridView.OnCellValueChangedInternal(DataGridViewCellEventArgs e)
   at System.Windows.Forms.DataGridViewCell.SetValue(Int32 rowIndex, Object value)
   at System.Windows.Forms.DataGridView.PushFormattedValue(DataGridViewCell& dataGridViewCurrentCell, Object formattedValue, Exception& exception)
   at System.Windows.Forms.DataGridView.CommitEdit(DataGridViewCell& dataGridViewCurrentCell, DataGridViewDataErrorContexts context, DataGridViewValidateCellInternal validateCell, Boolean fireCellLeave, Boolean fireCellEnter, Boolean fireRowLeave, Boolean fireRowEnter, Boolean fireLeave)
   at System.Windows.Forms.DataGridView.EndEdit(DataGridViewDataErrorContexts context, DataGridViewValidateCellInternal validateCell, Boolean fireCellLeave, Boolean fireCellEnter, Boolean fireRowLeave, Boolean fireRowEnter, Boolean fireLeave, Boolean keepFocus, Boolean resetCurrentCell, Boolean resetAnchorCell)
   at System.Windows.Forms.DataGridView.CommitEditForOperation(Int32 columnIndex, Int32 rowIndex, Boolean forCurrentCellChange)
   at System.Windows.Forms.DataGridView.ScrollIntoView(Int32 columnIndex, Int32 rowIndex, Boolean forCurrentCellChange)
   at System.Windows.Forms.DataGridView.ProcessDownKeyInternal(Keys keyData, Boolean& moved)
   at System.Windows.Forms.DataGridView.ProcessEnterKey(Keys keyData)
   at System.Windows.Forms.DataGridView.ProcessDialogKey(Keys keyData)
   at System.Windows.Forms.Control.ProcessDialogKey(Keys keyData)
   at System.Windows.Forms.TextBoxBase.ProcessDialogKey(Keys keyData)
   at System.Windows.Forms.Control.PreProcessMessage(Message& msg)
   at System.Windows.Forms.Control.PreProcessControlMessageInternal(Control target, Message& msg)
   at System.Windows.Forms.Application.ThreadContext.PreTranslateMessage(MSG& msg)

Also werden die Daten temporär gespeichert und erst irgendwann beim nächsten "wichtigen" Ereignis übernommen.
Kann mir vielleicht einer ein Tipp geben wie ich das umgehen kann, ich stehe momentan auf dem Schlauch, ansonsten bin ich gezwungen fremd zu gehen :mrgreen:

Re: MySqlDataAdapter aktualisiert nur manchmal.

Verfasst: So Aug 03, 2014 10:59 pm
von cloidnerux
das funktioniert:

Code: Alles auswählen

dataGridView1.Rows[dataGridView1.CurrentRow.Index].Cells["name"].Value.ToString()
das nicht:

Code: Alles auswählen

dataGridView1.Rows[dataGridView1.CurrentRow.Index].Cells["name"].Value.ToString()
da kommt ein Null Error:
Soll das das selbe sein?
Ich habe gerade ein wenig herumexperimentiert und rausgefunden das Datagridview ein bisschen buggy ist.
Meine bisherigen Erfahrungen mit WinForms Datencontainer war, dass diese generell etwas speziell sind.
Wenn du da nicht das richtige abfragst, kommt da gerne mal mist heraus.
Bist du dir sicher, dass du das richtige abfragst und nicht vlt doch das zugrunde liegende DataSet/DataTable anschauen solltest?

Re: MySqlDataAdapter aktualisiert nur manchmal.

Verfasst: Mo Aug 04, 2014 10:53 am
von canlot
Oh Danke, endlich eine Antwort ;)
cloidnerux hat geschrieben:Soll das das selbe sein?
Da habe ich in Eile doch das gleiche eingefügt. :roll:

Das zweite ist natürlich das, was Null zurückgibt:

Code: Alles auswählen

dataGridView1.Rows[dataGridView1.Rows.Count-1].Cells["name"].Value.ToString()
cloidnerux hat geschrieben:Meine bisherigen Erfahrungen mit WinForms Datencontainer war, dass diese generell etwas speziell sind.
Wenn du da nicht das richtige abfragst, kommt da gerne mal mist heraus.
Bist du dir sicher, dass du das richtige abfragst und nicht vlt doch das zugrunde liegende DataSet/DataTable anschauen solltest?
Ja das stimmt z.B. der Ereignis "UserAddedRow" wird ausgelöst wenn man eine Zeile hinzugefügt hat aber die Zeile mit den Daten wir erst mit der nächsten Zeile in den Bestand der Daten aufgenommen.
|bla|
|blabla|
|neue Zeile| <- diese Zeile ist nicht in den Bestand der Daten aufgelistet, da sie gerade neu hinzugefügt worden ist, sie ist unter currentRow aufrufbar aber nicht unter dataGridView1.Rows.Count-1


DataTable kriegt nur die Daten die ihr auch übergeben wurden was hier nicht der Fall ist.

Re: MySqlDataAdapter aktualisiert nur manchmal.

Verfasst: Mo Aug 04, 2014 11:37 pm
von londo
das sollte dich ans ziel bringen

Code: Alles auswählen

         MySqlConnection con = new MySqlConnection(login);
         MySqlDataAdapter adapter = new MySqlDataAdapter(opString, con);

         //damit DataTable INSERT, UPDATE, DELETE Statements richtig behandelt
         MySqlCommandBuilder cb = new MySqlCommandBuilder(adapter, true);

         tabelle = "deine änderungen";
         DataTable changes = tabelle.getChanges();
         adapter.Update (changes);
         tabelle.AcceptChanges();

für schreibfehler übernehm ich keine haftung...

Re: MySqlDataAdapter aktualisiert nur manchmal.

Verfasst: Mi Aug 06, 2014 9:52 pm
von canlot
londo hat geschrieben:das sollte dich ans ziel bringen
Nein leider hat mich es nicht ans Ziel gebracht, trotzdem Danke :cry:

Vielleicht hast du noch einen Vorschlag.

getChanges() gibt null zurück, wenn eine neue Zeile hinzugefügt wird.