Laden...

Forenbeiträge von kanedaa Ingesamt 39 Beiträge

11.07.2005 - 11:22 Uhr

ach so ich vergass, Vielen Dank 🙂

11.07.2005 - 11:17 Uhr

super das klappt.
Ich verstehe zwar nicht warum

this.receiptDS.Tables["ReceiptStuff"].Rows[0][9]

klappt,
aber

this.receiptDS.Tables["ReceiptStuff"].Rows[0].ItemArray[9]

nicht, aber egal 🙂

Das mit dem FeldName direkt klappt leider nicht (dachte eigentlich der DataAdapter würde die Feldnamen aus der DB 1:1 in das DataSet übernehmen?).
Nichtmal der Intellisense zeigt ihn mir an, lediglich bei

this.receiptDS.ReceiptStuff.M_NameColumn

ermöglicht er mir einen Zugriff auf irgendwas per Namen. Aber nicht auf die einzelnen Spalten selber...

11.07.2005 - 10:46 Uhr

Hallo allerseits!

Ich habe ein Typed DataSet, in dass ich gerne einen Wert per Hand einfügen würde. Dies funktioniert jedoch nicht (es geschieht einfach gar nichts).

Hier der Code:


string mName;
try 
{ 
        //receiptDA.Fill(receiptDS, "ReceiptStuff"); 
        mName= (string)emplCOM.ExecuteScalar(); 
        this.receiptDS.BeginInit(); 
this.receiptDS.Tables["ReceiptStuff"].Rows[0].ItemArray[9] = mName; 
        this.receiptDS.EndInit(); 

MessageBox.Show(this.receiptDS.ReceiptStuff.Rows[0].ItemArray[9].ToString()); 
        return true; 
} 
catch (Exception ex) 
{ 
        MessageBox.Show(ex.Message, "LoadMitarbeiter"); 
        return false; 
} 

(Der ExecuteScalar liefert auf jeden Fall den richtigen Wert zurück...)
Der Grund warum ich den Wert per Hand einfügen will ist folgender:
Dieses Typed DataSet ist die DataSource für einen CrystalReport.
Der Wert den ich hier einfüge kommt in eine bereits existente und bis auf diese Spalte mit genau einer Zeile gefüllte Tabelle.
Der Rest der Zeile wird mittels eines Selects(mit 3 Joins) zusammengestellt. Ursrüunglich wurde dieser Wert darin auch mitgeladen, jedoch kann er (neuerdings) auch null sein, und naja, wenn dass passiert, ist dass Resultat des gesamten Joins ja nix (zumindest kommt dann bei mir nix raus).

Daher hab ich diesen einen Wert aus dem join herausgenommen und wollte ihn "per Hand" nachträglich einfügen.
Benutze ich nämlich hierfür wieder einen DataAdapter, lädt dieser den Wert in eine 2te Tabelle "ReceiptStuff" (zumindest so sieht es im XML Schema aus, was ich durch receiptDS.WriteXML() bekomme.
Auf jeden Fall "findet" Crystal Reports diesen einzelnen Wert dann nicht, was ja darauf hindeutet, dass er zumindest nicht in der gleichen Zeile ist wie der Rest.

Es wäre zwar eine Option, in dem TypedDataSet eine weitere Tabelle zu erzeugen, und hier dann per AddxxxRow den Wert einzufügen.
Dafür müsste ich jedoch in dem Crystal Report die DataSource neu laden (einzelene Tabelle nachladen geht nich), und damit wäre die gesamte Formatierung futsch. Und das war ne Menge Arbeit...

27.06.2005 - 10:19 Uhr

ach so, der Pfad den er dann da einsetzt ist:
\\P-pc20\ErgoDB\ErgoPausen2.mdb.
Ohne die doppelten \ kommt dabei halt
\P-pc20\ErgoDB\ErgoPausen2.mdb heraus, was der richtige Pfad ist (über "äusführen" öffnet er damit die Datenbank, also wird er wohl stimmen...)

27.06.2005 - 09:47 Uhr

Moin zusammen!

Kann ich ohne weiteres zu einer Access DB connecten, wenn als Pfad im Connection String ein Netzwerklaufwerk angegeben ist?

Weil bei mir klappt das gerade nicht, dann kommt ein "Falscher Dateiname" Fehler.
Wähle ich (mittels eines OpenFileDialogs) in meinem Programm jedoch auf die gleiche Weise eine DB auf meinem lokalen Rechner, dann funktioniert es.
Also scheint es ja an dem OpenDialog Konstrukt nicht zu liegen ?!?!

Wäre ÄUSSERST praktisch wenn das ganze auch ohne weiteres per NEtzwerklaufwerk geht, dann muss ich nämlich nicht ein Server Programm schreiben (wofür ich ja sowas von keine Zeit habe...)

string path = this.mySettings._Path.Replace("\\" ,"\\\\");
myConnection.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source="+ path +" ;User Id=admin";

der path ist halt hierbei das was von dem OpenFileDialog zurückkommt.
Lokal funktioniert ist (auf meinem XP Rechner).
Wenn ich es auf den NT Rechnern mit dem Netzwerklaufwerk versuche funktioniert es nicht...

20.06.2005 - 11:23 Uhr

funzt alles wunderbar. MouseUp + GetItemAt und mein Kontextmenü macht genau das was es soll🙂

Vielen Dank nochmal!

20.06.2005 - 10:04 Uhr

Original von Noodles
Ich bekomme das richtige Item.
Du musste es auch selektieren um es zu bekommen oder Du nimmst das MouseUp Event.

Ja die Idee war ja, das es mit dem Rechtsklick auch schon selektiert wird.

Im Moment nehm einfach das normale Click Event des ListViews. Im Gegensatz zum SelectedIndexChanged liefert es mir auch sofort das richtige Item.

Aber die GetItemAt Mtehode ist wohl das was ich gesucht hab. War nur nicht schlau genug zu sehen, das man ihr Koordinaten übergibt (damit ist sie ideal), und nicht einen Index wie ich es irgendwie angenommen hatte...

Vielen Dank für die Hilfe an alle!

20.06.2005 - 08:24 Uhr

Servus allerseits!

Ich habe ein kleines Problem:
Ich habe ein Listview, dem, sofern er Elemente enthält ein Kontextmenü zugeordnet wird.
Der Gag soll aber sein, das wenn man im ListView (ist im Modus der Detailansicht) in den leeren Bereich klickt, ein Großteil der Menüoptionen deaktiviert sein soll.
Nur wenn man auf einen der Einträge, also auf eines der ListViews Items klickt, dann sollen alle Einträge des Menps wählbar sein.

So, das Knotextmneü zuordnen ist ja kein Problem.
Wenn nich nun das MouseDown Event abfange und mir vom Sender, dem Listview, das aktuell selektierte Element (ListView.SelectedItems[0]) = geben lasse, bekomme ich aber immer das letze.
Als würde es erst NACH dem Rechtsklick selektiert, und nicht wie beim Linksklick sofort.
So sieht der Code aus:

private void lstVw_Designs_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e) 
{ 
   string test = ""; 
   if (e.Button == MouseButtons.Right)       
   {                
      if (this.lstVw_Designs.SelectedItems.Count > 0) 
      {          
                       test =this.lstVw_Designs.SelectedItems[0].Text; 
          MessageBox.Show(test); 
      } 

      if (this.lstVw_Designs.SelectedItems.Count > 0) 
      { 
          test = (sender as ListView).SelectedItems[0].Text; 
          MessageBox.Show(test); 
      } 
   } 
} 

Hierbei ist es egal welche der beiden if-Anweisungen man nimmt, beide liefern das gleiche. Nicht das aktuelle selektierte, sondern das vorherige (bei der ersten Auswahl also keines.)

Ist die einzige Möglichkeit das aktuell selektierte zu bekommen, das ich mir die Pixelkoordinaten geben lasse und berechne in welchem Element ich bin?

18.05.2005 - 13:56 Uhr

Servus zusammen,

ich habe ein kleines Problem.
In meinem Programm gibt es 4 DateTimePicker die per DataBinding an eine Access DB gebunden sind.
Vor jedem DateTimePickern befindet sich jeweils eine Checkbox (hab aus design Gründen nicht die des DateTimePickers benutzt).
Ist die Checkbox aktiviert, wird das Datum in die Datenbank geschrieben.
Ist sie deaktiviert, dann wird NULL oder "" in die DB geschrieben (ist ja erstmal egal).

Soweit die Theorie, nun die leidliche Praxis:
Das Pushen der Daten aus der DB in den DateTimePicker funktioniert.
Ist kein Wert in der DB eingetragen, wird im Format Event des DataBindings die Checkbox "unchecked" und damit der DateTimepicker disabled.

Dummerweise bekomme ich aber das Parse Event nicht zum laufen.
Laut MSDN "feuert" dieses:
* after the Validated event of the Control object occurs.
* when the EndCurrentEdit method of the BindingManagerBase is called.
* when the Current object of the BindingManagerBase changes (in other words, when the Position changes).

Nun ich habs alles nach meinem Wissen (welches noch sehr bescheiden ist) ausprobiert, nix hilft.
Ich hab ein validated Event erzeugt (zu validaten gibt es da eigentlich nix, daher wüsste ich nich was ich mit e anfangen soll).

private void dTP_Freigabe_Validated(object sender, System.EventArgs e)
{
MessageBox.Show("dTP_Freigabe_Validated");
}

Ich habs über den CurrencyManager versucht:

			
CurrencyManager cm = (CurrencyManager)BindingContext[Ergo.MainApp._DesignDB._SelDesignDV];
			
cm.EndCurrentEdit();

Gleiches Spiel mit der BindingManagerBase.
Ich hab sogar die Position des CurrencyManagers geändert

cm.Position += 1;

Hat alles nicht funktioniert.
Ich weiss aber, das es in der Theorie geht.
Die DataSource ist ein DataView (_SelDesignDV ist die Property dazu).
Das Binding wird folgendermassen erzeugt (und funktioniert ja auch sonst):

Binding bind = new Binding("Text", Ergo.MainApp._DesignDB._SelDesignDV, "Freigabe_Datum");
bind.Parse  +=new ConvertEventHandler(bind_Parse);
bind.Format +=new ConvertEventHandler(bind_Format);		
this.dTP_Freigabe.DataBindings.Add(bind);

Die Events sehen so aus:

		
private void bind_Format(object sender, ConvertEventArgs e)
{
	if (e.Value.ToString() == "")
		this.chBx_Freigabe.Checked = false;
	else
		this.chBx_Freigabe.Checked = true;
}
	
private void bind_Parse(object sender, ConvertEventArgs e)
{	
	MessageBox.Show("Holla");
	if (!this.chBx_Freigabe.Checked )
		e.Value = "";
	else
		e.Value = this.dTP_Freigabe.Text;
}

Kann mir da jmd. helfen?
(und ja, bitte nicht schlagen das ich beim Datum mit strings und nicht DateTimes hantiere, ist einst aus Zeitnot enstanden, und mittlerweile hab ich gar keine Zeit mehr mich darum zu kümmern...)

26.04.2005 - 14:33 Uhr

hm ich hab ne Lösung...

da ich Reports an DataSet binden kann, erzeuge ich mir ein typisiertes DataSet (zur DesignZeit) und fülle des im Laufe des Proggies mit den richtigen Daten und gut ist.
Da der Report zur DesignZeit an eben jenes DataSet gebunden wird, müsste doch nun alles peachy sein.
Wie toll, das ich die eine Zeile in der MSDN mit dem binden an DataSets überlesen haben, grmblx...

http://report.sourceforge.net/ sieht sehr gut aus, nur sehe ich da nicht das dort auch irgendwie Tabellen erstellt werden können. Das zu erweitern übersteigt aber zur Zeit meine Fähigkeiten und meinen Zeitrahmen 🙂

26.04.2005 - 14:15 Uhr

ist das ein definitives "nein" für die anderen oder "ich weiss es nur bei den Reporting Services des SQL Servers mit Bestimmtheit"?
🙂

26.04.2005 - 12:11 Uhr

Danke für die Tipps!

Aber ien konkrete Frage habe, zur generellen Fähigkeit dieser Reporte.

Wenn ich ihnen eine DatenBank als DataSource gebe, kann ich dann eine Einschränkung im Sinne von "WHERE projectID = xyz" machen?

Dass das zur Designzeit geht, weiss ich, ich würde nur gerne sichergehen (bevor ich massig Zeit investiere für lulu) das sowas auch zur Laufzeit geht, immerhin bestimmt der user die projectID...

25.04.2005 - 13:59 Uhr

Hallo zusammen!

Mein Programm muss mehrere Dokumente erstellen können, darunter u.a. ein Anschreiben und eine Liste über alle Firmen und sowas in der Art.
Die Daten stammen, bis auf immer gleichen Text, der bei der Formatierung festgelegt werden sollte, komplett aus einer Access Datenbank.

Gibt es da eine Alternative zu Crystal Reports?
Oder anders herum gefragt: Wäre es totaler Blödsinn NICHT Crystal Reports zu benutzen?

Oder gibt es sowas wie ne DocumentBuilder class, mit der ich mir ein Dokument erstellen und vorformatieren kann?

24.04.2005 - 19:34 Uhr

tja, soweit so gut 🙂

Man stolpert von einem Prob ins andere...

			
DataColumn NrName = new DataColumn("NrName");
NrName.DataType = System.Type.GetType("System.String");

NrName.Expression = "BV_Nr \t+  BV_Name";
projectsDS.Tables["Projekte"].Columns.Add(NrName);

Der Trick mit den tabs \t klappt leider (natürlich?) nicht (da wo da oben t steht sollte \t stehen ...).

Einzige Lösung die mir auf Anhieb einfällt, wäre pro Spalte berechnen wie lang der BV_Nr String is, und abhängig davon soviele whitespaces einfügen das BV_Name wieder bündig ist.
Das wäre dann aber für jede Zeile neu, was ja dann nicht geht da die Expression property für die ganze column gilt.
Es sei denn ich kann sie in einer Foreach schleife jede Zeile neue setzen.
Und nen neuen proportionalen Font muss ich dann auch nehmen bei dieser Billig Lösung...

Ach herrje...

24.04.2005 - 18:12 Uhr

super, danke für den Tipp das werde ich mir mal genauer anschauen.

Auf eine mögliche Lösung in der Art hatte ich gehofft!

24.04.2005 - 17:36 Uhr

Ich ernenne dich hiermit offiziell zu meinem (vorläufigen 🙂 ) Retter der Woche!

Du hast (in Kombination mit dem Tip, in meinem Select schon ORDER BY zu benutzen) alle meine Probs gelöst.

* der Mist ist sortiert
* das Textfeld der ComboBox bleibt leer bis zu einem expliziten select
* ich bekomme meinen ValueMember

Allerdings:
Was mache ich nun wenn ich die strings in der ItemCollection aus zwei Spalten zuasmmengesetzt werden sollen?

In der For-schleife wäre das ja leicht gegangen, aber dafür hätte ich da keinen ValueMember gehabt.

Letzteren hab ich nun, aber wie schaffe ich es das letztenendes vom Sinn her sowas in der Art herauskommt❔

this.cmbBx_SelectProjekte.DisplayMember = "BV_Name" + "BV_Nr";

Das geht wahrscheinlich dann wieder gar nicht oder?
Der Versuch ValueMember in der For schleife zu füllen ist leider gescheitert, der Indexer scheint Read-only zu sein.

Ich fürchte da muss ich einmal (diese Mischung brauch ich nur bei einer ComboBox) doch per for schleife füllen (und dabei die zusammen gesetzen strings), und parallel ein Array mit den einzelnen Werten...
Hoffentlich geht das nicht alles irgendwann auf die Performance...

24.04.2005 - 14:23 Uhr

naja ich glaube ich habe die Ursache gefunden.
Wenn meine ComboBox nicht im DropDown Event, sondern beim start des Programmes gefüllt wird funzt

this.cmbBx_SelectProjekte.DataSource    = ergoDB._ProjectsDS.Tables["Projekte"];
this.cmbBx_SelectProjekte.DisplayMember = "BV_Name";
this.cmbBx_SelectProjekte.ValueMember   = "ID_Projekt";

einwandfrei.
Aber mit eklatanten Nachteilen!

Sorted Property:
Setze ich die Sorted Property auf true, gilt das nur für die DisplayMember, aber NICHT für die ValueMember. Folge: Die SelectedValue Property liefert den falschen Wert (ich wähle 2.Element der SORTIEREN ComboBox Liste und bekomme den Value des 2. Elementes in der Tabelle (nicht sortiert), was also nicht passt. Ich brauche es aber sortiert....

Erster Eintrag in der ComboBox:
Startet das Programm, ist sofort der erste Eintrag lesbar. Fülle ich die Box aber per forschleife, bleibt das Textfeld der Box solange leer, bis ich ein Element explizit auswähle. Das muss auch so sein, weil sobald ein Element gewählt ist, massig Funktionen ausgeführt werden. Die werden so sofort ausgeführt, dabei hat der user noch nix gewählt. Sehr suboptimal.

Erstelle meine DataSources erst zur Laufzeit:
Diesen ComboBox-Füller beim programmstart kann ich NUR bei einer ComboBox machen, alle anderen DataSourcen können erst zur Laufzeit erstellt werden.
Damit ich die DataSourcen schon vorher setzen kann, müsste ich ja demenstprechend alle meine DataSets beim Programmstart initialisieren und mit leeren Tabellen füllen. damit die Bindings keine Fehler liefern.
Ebenfalls sehr suboptimal.

Nun stehe ich da. Meine ComboBox muss dummerweise mit zusammengesetzen Strings (ProjektNr + ProjketName) gefüllt werden.
Wird eines ausgesucht, müssen aber beie werte getrennt weiterverarbeitet werden.
Sie mir dann wieder aus den strings rauszufriemeln, gibt nen nerviges Gehacke.
Daher hätte ich schon gerne die ValueMember Property, aber so geht es ja nicht...
Und sie per Hand in der For schleife selber füllen geht auch nicht....

Ist C# da so sch**sse, oder hab ich irgendwo was gewaltig zersägt bei mir?

22.04.2005 - 17:45 Uhr

stimmt, der SqlXmlAdapter nimmt nur des DataSet. Wusste nich das der sich grossartig anders verhält als die OleDBDataAdapter...

22.04.2005 - 16:14 Uhr

du hast ein untypisiertes DataSet?
Dann versuch mal ihm bei der FIll und der Update Methode den Tabellennamen mit anzugeben, also Adapter.Fill (DataSet, TabelleName)?

Oder ist das bei xml alles anders?

22.04.2005 - 12:49 Uhr

stimmt. denn die 0-Spalte ist die Spalte "Name", die ich sonst direkt dahin geschrieben hab.
Somit machen doch beide das gleiche oder ?
Ich mein, wenn ich bei einer Listbox DisplayMember auf "Firmen.Name" (Tabelle.SpaltenName) setzen kann (und es funktioniert), muss das doch hier auch gehen. Ich dachte das wäre der Sinn von DisplayMember, das man ihm die Spalte gibt, aus der er die Information holen soll.

Und in diesem Falle wäre das "Mitarbeiter.Name".
Und wäre in den Feldnamen in Schreibfehler, müsste das Proggie mir doch ne Exception schmeissen oder zumindest abnippeln, da dann ja da was drin steht was er nicht kennt.

Also bin ich jetzt völlig verwirrt? 🙂

Meiner For schleife sage ich halt explizit, das sie die 1.Spalte der Tabelle durchrattern soll und die Werte in die ComboBox packen soll.
Wenn ich DisplayMember eben jene 1.Spalte gebe, dann müsste das doch automaitsch geschehen.
Bei meiner Listbox geschieht es ja auch automatisch ....

22.04.2005 - 09:18 Uhr

Original von FZelle
Du solltest Dir nochmal durchlesen was Programmierhans geschrieben hat.

Wenn Du eine DataTable an ein Control bindest darfst Du nur die Feldnamen übergeben.

Nimmst Du ein DataSet, musst Du Tabelle.Feldname nehmen.

Auch ist Gross/kleinschreibung wichtig.

Auch kannst Du nicht 2 Tabellen an ein Controll binden.
Displaymember und Valuemember müssen auf die selbe Tabelle zeigen.

das mit den 2 Tabellen ist ein Copy/Paste Fehler, der hatte hier nix zu suchen.
Gross und Kleinschreibung, naja, da würde ich doch wohl entweder nen Compilerfehler oder ne Exception beim Binding bekommen, oder nicht?
Und wie gesagt:
Es ist völlig egal ob ich an Tabelle.Fieldname oder nur Fieldname binde.
Es geschieht NIX, das macht mich ja so kirre.

Und @ Programmierhans: Da sind jetzt inhaltlich 2 Sachen vermischt worden.

Meine Combobox soll nur per simple Binding einen Haufen Firmen anzeigen.

Das complexe Binding bezieht sich auf eine Listbox in der man einen Mitarbeiternamen auswählen kann, der darunter dann in einer Textbox erscheint (und dort bearbeitet werden kann etc..)

Das Listbox Problem hat sich erledigt.
Nur würde ich wirklich gerne mal meine ComboBoxen eleganz füllen 🙂

21.04.2005 - 17:12 Uhr

irgendwas funzt bei mir hier immer noch nicht richtig:
(und da ist es egal ob ich bei DisplayMember "TableName.ColumnName" oder nur "ColumnName" schreibe:

this.lstBx_Ansprechpartner.DataSource    = Ergo.MainApp._EmployeeDB._EmployeeDS;			
this.lstBx_Ansprechpartner.DisplayMember = "Mitarbeiter.Name";

this.txtBx_Name.DataBindings.Add("Text", Ergo.MainApp._EmployeeDB._EmployeeDS, "Mitarbeiter.Name");

naja da passiert nix, dabei ist das Dataset 100% gefüllt.
An anderer Stelle ich meinem Programm mache ich genau das gleiche, und es ging sofort einwandfei...

Ähnliches Problem bei der schon "besprochenen" ComboBox.
Da tut sich nix, egal ob ich den TableName nochmal mit angebe oder nicht.

			
this.cmbBx_Empfaenger.DataSource = Ergo.MainApp._ErgoDB._SelFirmsDS;
//	this.cmbBx_Empfaenger.DisplayMember = "Mitarbeiter.Name";
//	this.cmbBx_Empfaenger.ValueMember   = "Firmen.ID_Firma";
try
{				
int length = Ergo.MainApp._ErgoDB._SelFirmsDS.Tables["Firmen"].Rows.Count;							
for(int i=0; i<length; i++) 	
this.cmbBx_Empfaenger.Items.Add(Ergo.MainApp._ErgoDB._SelFirmsDS.Tables["Firmen"].Rows[i].ItemArray[0]);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Fehler beim setzen der DataSource und laden der Daten");
}

nehme ich das auskommentierte wieder rein und die forschleife raus, passiert nix.
egal wie ich DisplayMember angebe. Bestenfalls wird eine lange, aber leere Klappliste bei der ComboBox geöffnet.
Die Daten erscheinen aber NUR bei der FOr schleife?!?!?

Ich weiss echt nicht welchen komischen Verdreher ich hier drin habe.
Ich bin zwar noch relaitv neu in .Net/Ado.Net, aber mein Programm ist mittlerweile schon recht umfangreich, und zumindest die listbox hab ich schon mal erfolgreich gefüllt (meine ComboBoxen aber immer über For-schleifen...

20.04.2005 - 11:47 Uhr

aso ich dachte bei einem untypisierten DataSet müsste man immer schön fleissig den Tabellen Namen mitangeben...

Danke auf jeden Fall!

20.04.2005 - 10:18 Uhr

Holdrio, hab da irgendwie ein nerviges Problem was ich zwischenzeitlich umgangen hab, aber das doch jetzt wieder "aufstösst".

Ich will eine ComboBox an eine DataSource binden.

this.cmbBx_Empfaenger.DataSource = selFirmsDS.Tables["Firmen"];

this.cmbBx_Empfaenger.DisplayMember = "Firmen.Name";
this.cmbBx_Empfaenger.ValueMember   = "Firmen.ID_Firma";

Die Sorted-Property steht auf true, das DataSet(untyped) ist 100% korrekt gefüllt.
Packe ich obiges ins DropDown Event und öffne die ComboBox, stimmt zwar die Länge der geöffneten Box, aber die Einträge sind leer.

Mach ich das ganze ganz direkt über eine For-Schleife

int length = selFirmsDS.Tables["Firmen"].Rows.Count;							
for(int i=0; i<length; i++) 		
     this.cmbBx_Empfaenger.Items.Add(selFirmsDS.Tables["Firmen"].Rows[i].ItemArray[0]);

funzt es, is aber irgendwie unschön.

Noch besser wirds, wenn ich die Sorted Property nich auf true setze, dann steht in meiner ComboBox nur System.Data.RowView.

Woher kommt das?
Welchen dämlichen Fehler mache ich?
Bisher war es egal, die For schleife hat gereicht, aber nun würde ich ganz gerne die ValueMember Propery utensilieren, das is aber schlecht wenns net funzt 🙂

20.04.2005 - 10:05 Uhr

Binde deinen RadioButton per DataBindings.Add an die DB (vorrausgesetzt, die Spalte an die du bindest enthält bool Werte).
also zum Bsp:

myRadioButto.DataBindings.Add("Checked", myDataSet, "TableName.ColumnName");

ich glaub so wars...

12.04.2005 - 11:11 Uhr

hast du es schon mal mit einem complexen Binding versucht?
Mittels

DataGrid.DataSource = deinDataSet/Tabelle...
DataGrid.DisplayMember = DataSet.Spalte...

dann setzt zu für jede Textbox das Binding mittels

txtbox.Bindings.Add("Text", deinDataSet, "Tabellenname.Spaltenname");

Klappt bei mir (allerdings mittels einer Listbox) ganz einwandfrei:


this.lstBx_Firmen.DataSource    = myDataSet;
this.lstBx_Firmen.DisplayMember = "Firmen.Name";
this.lstBx_Firmen.ValueMember   = "Firmen.ID_Firma";
							
this.txtBx_Name.DataBindings.Add("Text",   myDataSet, "Firmen.Name");
this.txtBx_Zusatz.DataBindings.Add("Text", myDataSet, "Firmen.Zusatz");
...

this.lstBx_Firmen.ValueMember ist glaube ich sogar egal, ist noch aus der Rumtesterei enstanden. So wie ich es verstehe, lege ich damit einen zusätzlichen Wert fest, den ich bekomme wenn ich etwas selektiere.

08.04.2005 - 10:10 Uhr

wunderbar, hat sich erledigt, habe (mit Hilfe) folgendes in der MSDN gefunden...

  protected static void OnRowUpdated(object sender, OleDbRowUpdatedEventArgs args)
  {
    // Include a variable and a command to retrieve the identity value from the Access database.
    int newID = 0;
    OleDbCommand idCMD = new OleDbCommand("SELECT @@IDENTITY", nwindConn);

    if (args.StatementType == StatementType.Insert)
    {
      // Retrieve the identity value and store it in the CategoryID column.
      newID = (int)idCMD.ExecuteScalar();
      args.Row["CategoryID"] = newID;
    }
  }

und die sache is geritzt...

08.04.2005 - 08:10 Uhr

Hallo zusammen!

Ich habe nicht unbedingt ein Problem, sondern suche einen "alternativen" Lösungsweg.
Ich hab einen DataAdapter samt DataSet und Commandbuilder.
Funzt alles ganz wunderbar.

Aber: Ist es möglich, das die Update() Methode des DataAdapters mir bei einem Insert den neu erzeugten Primary Key (ist eine AutoWert Spalte in der Access DB, also mein Programm generiert ihn nicht) zurückliefrt?

Soweit ich wess geht das ja mit mit DataCommands, also zum Bsp commandxyz.ExectuteScalar().
Dann aber kann ich meinen doch recht komfortablem CommandBuilder nicht mehr benutzen.
Das ist nicht nur unbedingt aus Faulheitsgründen ärgerlich, sondern anderes kostet a) Zeit und b) ob ICH es besser mache als der Commandbuilder is so ne Sache 😉.

Zumindest glaube ich das es recht praktisch werden könnte, dass er äusserst extensive WHERE-Klauseln generiert, in denen die aktuellen Werte der DB nochmal gechecked werden, ob sie sich mittlerweile geändert haben?

Von soher versuche ich ihn eigentlich zu erhalten.
Oder kann ich mir einfach parallel zum Commandbuilder selber ein INSERT Command schreiben (was ja nun wirklich einfacher is), und das dann selber per ExecuteScalar ausführen?
Nicht das sich nachher Commandbuilder und selbstgebasteltes Command in die Quere kommen...?

02.04.2005 - 01:20 Uhr

grmblfx, ich hab den Fehler.
EndCurrendEdit geht nur dann, wenn ich zusätzlich zum DataSet auch den Tablename angebe.
Ich benutze ja ein untypisiertes DataSet....

30.03.2005 - 12:18 Uhr

Musst du nicht den Typ der Parameter angeben?
Sowas wie OleDbType.VarChar (je nachdem was du in die DB schreiben willst)?

30.03.2005 - 11:27 Uhr

eine Frage hab ich dann leider doch noch:
War evtl etwas voreilig mit dem "es klappt alles auf Anhieb".

Wenn ich per DataBinding Textboxen an ein DataSet gebunden habe, dann wird ja doch das DataSet automatisch geupdadet, wenn ich in der Textbox etwas ändere.

Müsste dann nicht

BindingContext[theDataSet].EndCurrendEdit();

reichen, um dem DataSet mitzuteilen, das die Änderungen fertig sind und er die jeweiligen Rows als "geändert" markieren kann?
Weil sobald das der Fall ist, musste dann ja die Update Methode (mit vorherigem Commandbuilder) zum Update der Datenbank reichen.

Bisher klappt nämlich nur der Insert einwandfrei, aber dabei muss ich ja eh erst eine neue Row im DataSet anlegen.



newRow = theDataSet.Tables["Zeichnungen"].NewRow();
newRow["ID_Zeichnung"] = nr;
newRow["Bezeichnung"] = bez;
newRow["Typ"] = 0000;
newRow["Geschoß"] = "0000";
newRow["Bauteil"] = "0000";
newRow["Bereich"] = "0000";
newRow["ErstKosten"] = erstk;
newRow["AenderKosten"]   = aendk;
theDataSet.Tables["Zeichnungen"].Rows.Add(newRow);

Diese explizite DataSet Änderung nehme ich ja (zumindest bis jetzt) nicht beim Update vor.
Sie kommen ja auch im DataSet an (sehe ich per WriteXML), aber trotz EndCurrentEdit tut sich nichts.

30.03.2005 - 10:21 Uhr

Ja hat alles wunderbar geklappt. Im ersten neuen Fenster ging es sofort einwandrei so, wie ich es die ganze Zeit schon (woanders) versucht hatte.
Werde jetztmeinen ganzen Code überarbeiten, bei dem Mist den ich mir zu Beginn zusammengeflickt habe komme ich in Teufelsküche mit komplexen Databindings.
Die Lernkurve bei so einem Projekt is doch faszinierend teilweise.
Manchmal könnte man alle 2-3 Wochen den ganzen alten Code wegschmeissen und neuschreiben...
Aber jedenfalls gehts endlich wieder vorwärts.
Vielen Dank!

29.03.2005 - 22:40 Uhr

Holla, dann hab ich ja erstmal ordentlich was zu tun.
Hoffentlich hab ich Glück und kann einfach immer Odbc durch OleDB in den Konstruktoren ersetzen....

Aber nett von MS, das des in der MSDN so eindeutig drinsteht, wenn deine Lösung bei mir funzt, dann
a) freu ich mich zwar, bekomme aber auch
b) einen infernalen Brechreiz wieviel Zeit mich dieser Verständnis/Informationsfehler kostet...

Auf jeden Fall vielen vielen Dank für deine Hilfe!

29.03.2005 - 20:37 Uhr

Vorab: Danke für die Hilfe!

Original von FZelle

  1. Warum benutzt Du den ODBCAdapter? Der ist nur noch zu benutzen,
    wenn wirklich kein anderer Treiber für die DB vorhanden ist.
    Für Access ist das aber OleDb mit dem Jet4.0.

hm ich dachte gerade Odbc wäre für Access gedacht? Ich mein es funktioniert ja, sollte ich trotzdem wechseln(is ja kein Aufwand), evtl wegen Performance?

EDIT: gerade bei MSDN gefunden:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconADONETProviders.asp

Demnach wäre Odbc doch nicht so falsch ( da ich ja eine *.mdb Datenbank habe...).

  1. Der DataAdapter benötigt keine Update/insert/Delete fürs fill, sondern
    für das Update, und da brauch er auch keine Werte in den Parametern,
    die würde er sich selber holen.

Die Commands nicht nicht für das Fill, sondern für das Update!
Ich mache halt nur (erstmal) DataSet Init und DataAdapter in einer Funktion.
Wenn ich ihm die Parameter nicht gebe, funzt es ja gar nicht.
Das ist ja einer der Punkte die mich so aufregen. Ich weiss das er sich die selber holen müsste, er tuts aber nicht!

  1. Die Daten stehen erst dann in dem DataSet, wenn Du entweder den Datensatz
    verlässt und einen anderen Editierst, oder per
    BindingContext[Ergo.MainApp._FirmDB._FirmsDataSet].EndCurrendEdit() abschliesst.

Aber wenn ich mir das DataSet in eine XML Datei schreiben lasse, sehe ich sofort die Änderungen. Ich hatte es mit EndEdit() probiert das ging nicht, werde EndCurrentEdit ausprobieren.
Sowas hatte ich mir schon gedacht (ein expliziter Wechsel des SelectedItem in der Listbox hatte ja auch diesen Effekt). Allerdings bekam ich dann ( als der DataAdapter endlich seinen Job machen wollte) die nervige Fehlermeldung (s.o.)...

  1. Unter .NET und allen modernen Sprachen benutzen wir diese ungarische
    Notation nicht mehr. Die Varaiblen heissen dann z.B. FirmenListe stat
    lstbx_Firmen und so weiter.
    Auch solltest Du vermeiden Zeilenlange Variablennamen zu benutzen, dann
    kann/mag keiner deine Sourcen lesen, weil sie unübersichtlich sind.

Die Variablennamen werden auch noch geändert, das nervt mich ja auch.
Die Ungarische Notation war nicht bewusst, erschien mir so erstmal sinnvoll, (ich mache das auch nur bei GUI-Controls, ansonten schreib ich auch nicht bei einem int iVar oder sowas...) . Und das die so lang werden liegt auch an meiner Staffelung in Klassen und namespaces.
Aber da die Objekte alle im Hauptfenster (Ergo.MainApp) erzeugt werden, konnte ich halt nur so über Properties auf die Objektinstanzen zugreifen.
Und momentan habe ich soviel Zeitdruck, das ich mich um eine "Umorganisation" im grösseren Maßstab erstmal nicht kümmern.Leider...

  1. Da dein Select/Update nun wirklich keine Spezialitäten enthält,
    warum nimmst Du nicht den Commandbuilder?

Weil es nicht funktioniert hat, und ich es richtig "lernen" wollte.

  1. Wo setzt Du das Select/UpdateCommand des DataAdapters?

Das was du da siehst sind die Select/Update COmmands des DataAdapters.
Hatte den Teil des Codes vergessen hier hin zu schreiben, wo sie zugewiesen werden...


firmsDataAdapter.SelectCommand = selectCom;
firmsDataAdapter.UpdateCommand = updateCom;
firmsDataAdapter.InsertCommand = insertCom;
firmsDataAdapter.DeleteCommand = deleteCom;
firmsDataAdapter.MissingSchemaAction = MissingSchemaAction.AddWithKey;	


29.03.2005 - 02:41 Uhr

um nochmal die verschiedenen "Szenarien" zu nennen:

lasse ich diese Zeile


this.lstBx_Firmen.SelectedIndex = -1; 

weg, und benutze diese


updateCom.ExecuteNonQuery();  

für den Update zur Datenbank, kommen sie auch dort an.
Das DataSet bekommt sie auch (in der XML Datei erscheinen sie), aber gleichzeitig bleibt das DataSet bei der Meinung, es wäre nicht geändert worden... ?!?!?

wenn ich andersherum diese Zeile

: 
this.lstBx_Firmen.SelectedIndex = -1; 

drinlasse, und den Update per


firmsDataAdapter.Update(firmsDataSet, "Firmen");  

ausführe, bekomme ich die Fehlermeldung
"ERROR [HY090] - Ungültige Zeichen oder Pufferlänge".

also irgendwo ist doch da gewaltig der Wurm drin.
Warum weigert sich das DataSet, die Änderung, die es ja bekommt, als solche wahrzunehmen?

28.03.2005 - 23:48 Uhr

Hallo zusammen!

Ich habe ein etwas merkwürdiges Problem, an dem ich völlig verzweifele (u.a. weil ich sehr viel Zeitdruck hab, und schon sehr viel Zeit in dieses Problem investiert habe)
Ich bin für jegliche Hilfe EXTREM dankbar!!

Ich benutze einen ODBCDataAdapter (mit selbstgebastelen Select, Update ect Commands), ein untypisiertes DataSet und eine Access DB.
In meinem Fenster ist eine Listbox, die mir per Binding Firmennamen anzeigt.
Darunter sind Textboxen für die Firmendetails.
Wähle ich einen aus, werden unten die Details der Firma angezeigt. Das ganze funzt einwandfrei per DataBinding.
Nun gehts aber los:
Ich wähle eine Firma aus. Ich ändere ihren Namen.
Wenn ich nun firmsDataSet.HasChanges() abfrage, sagt er mir keine Änderung. Obwohl die Änderung im DataSet ist (das sehe ich wenn sie mir in eine XML Datei schreiben lasse).
Die einzige Möglichkeit, die mein DataSet davon überzeugt, die RowState Property richtig zu setzen, ist wenn ich in der Listbox NACH der Ändernung den SelectedIndex auf -1 (also keines) setze. DANN ergibt HasChanges true, und per Binding wird auch der neue Name in der Listbox angezeigt
Aber als wenn nun alles gehen würde...
Rufe ich nun die Update-Methode des DataAdapters auf, bekomme ich den ERROR [HY090] - Ungültige Zeichen oder Pufferlänge.
Aber an dem UpdateCommand des Adapters kann es aber eigentlich nicht liegen, denn wenn ich einfach updateCom.ExecuteNonQuery(); aufrufe, updated er die Datenbank (mit falschen Daten, aber das liegt wohl an meiner Parameterzuweisung), ABER der Name in der Listbox wird NICHT geändert (im Textfeld Name darunter aber wird wiederum der richtige angezeigt).

So hier der Code:

Zuerst die DataBindings:


	this.lstBx_Firmen.DataSource    = Ergo.MainApp._FirmDB._FirmsDataSet;
	this.lstBx_Firmen.DisplayMember = "Firmen.Name";						
															
	this.txtBx_Name.DataBindings.Add("Text", Ergo.MainApp._FirmDB._FirmsDataSet, "Firmen.Name");
	this.txtBx_Zusatz.DataBindings.Add("Text", Ergo.MainApp._FirmDB._FirmsDataSet, "Firmen.Zusatz");			
	this.txtBx_Straße.DataBindings.Add("Text", Ergo.MainApp._FirmDB._FirmsDataSet, "Firmen.Straße");
	this.txtBx_Ort.DataBindings.Add("Text", Ergo.MainApp._FirmDB._FirmsDataSet, "Firmen.Ort");
	this.txtBx_PLZ.DataBindings.Add("Text", Ergo.MainApp._FirmDB._FirmsDataSet, "Firmen.PLZ");
	this.txtBx_Postfach.DataBindings.Add("Text", Ergo.MainApp._FirmDB._FirmsDataSet, "Firmen.Postfach");
	this.txtBx_Tel.DataBindings.Add("Text", Ergo.MainApp._FirmDB._FirmsDataSet, "Firmen.Tel_Nr");
	this.txtBx_Fax.DataBindings.Add("Text", Ergo.MainApp._FirmDB._FirmsDataSet, "Firmen.Fax_Nr");
	this.txtBx_Mobil.DataBindings.Add("Text", Ergo.MainApp._FirmDB._FirmsDataSet, "Firmen.Mobil_Nr");
	this.txtBx_Mail.DataBindings.Add("Text", Ergo.MainApp._FirmDB._FirmsDataSet, "Firmen.E_Mail");

ohne diese Zeile weigert sich das DataSet, jegliche Änderung anzuerkennen:


	this.lstBx_Firmen.SelectedIndex = -1;
	

hier der Init des Adapters und des DataSets (Insert/Delete Teil weggelassen):


	private void BuildUpDataSet()
	{
		firmsDataAdapter = new OdbcDataAdapter();
		firmsDataSet     = new DataSet("FirmenDataSet");	
		
		
		// ==============
		// SELECT command
		// ==============
		string selectStr      = "SELECT * FROM Firmen";
		OdbcCommand selectCom = new OdbcCommand(selectStr, Ergo.MainApp._ErgoDB._MyConnection);
			
		// ==============
		// UPDATE command
		// ==============
		string updateStr = "UPDATE Firmen SET " +
						   "Name = ?, Zusatz = ?, Ort = ?, PLZ = ?, " +
						   "Postfach = ?, Straße = ?, Tel_Nr = ?, " +
						   "Fax_Nr =?, Mobil_Nr = ?, E_Mail = ? " +
						   "WHERE ID_Firma = ? ";
		updateCom = new OdbcCommand(updateStr, Ergo.MainApp._ErgoDB._MyConnection);
	
		// add the parameters to the collection
		updateCom.Parameters.Add("Name",   OdbcType.Text,  50, "Firmen.Name");
		updateCom.Parameters.Add("Zusatz", OdbcType.Text, 100, "Firmen.Zusatz");
		updateCom.Parameters.Add("Ort",    OdbcType.Text,  50, "Firmen.Ort");
		updateCom.Parameters.Add("PLZ",	   OdbcType.Text,  50, "Firmen.PLZ");
		updateCom.Parameters.Add("Postfach", OdbcType.Text,50, "Firmen.Postfach");
		updateCom.Parameters.Add("Straße", OdbcType.Text, 100, "Firmen.Straße");
		updateCom.Parameters.Add("Tel_Nr", OdbcType.Text,  50, "Firmen.Tel_Nr");
		updateCom.Parameters.Add("Fax_Nr", OdbcType.Text,  50, "Firmen.Fax_Nr");
		updateCom.Parameters.Add("Mobil_Nr", OdbcType.Text,50, "Firmen.Mobil_Nr");
		updateCom.Parameters.Add("E_Mail", OdbcType.Text,  50, "Firmen.E_Mail");
	
		// add the primary key parameter
		OdbcParameter pU = new OdbcParameter("ID_Firma", OdbcType.Int, 50, "Firmen.ID_Firma");
		pU.SourceVersion = DataRowVersion.Original; 
		updateCom.Parameters.Add(pU);
	
		// fill the dataSet			
		try
		{
			firmsDataAdapter.Fill(firmsDataSet, "Firmen");
		}
		catch(OdbcException ex)
		{
			MessageBox.Show(ex.Message, "Fehler beim Füllen des DataSets");
		}
		
		// set primary key column
		DataColumn [] keys = new DataColumn[1];
		keys[0] = firmsDataSet.Tables["Firmen"].Columns["ID_Firma"];
		firmsDataSet.Tables["Firmen"].PrimaryKey = keys;
	}


und hier schließlich das vermeindliche Datenbank Update:


	try
	{
		
		string firmID = GetFirmID(oldName);  // gibt mir den primary key der ausgewählten Firma, das funktioniert auch
		if (firmID != null)// && (CheckValues(newName)))
		{	
			
			// die explizite Wertzuweisung an die Parameter würde ich mir SEHR gerne sparen
			// aber dann geht es nicht, Der DataAdapter holt sich nicht selbstständig die
			// neuen Werte aus dem DataSet
			firmsDataAdapter.UpdateCommand.Parameters["Name"].Value	  = newName;
			firmsDataAdapter.UpdateCommand.Parameters["Zusatz"].Value = newZusatz;
			firmsDataAdapter.UpdateCommand.Parameters["Ort"].Value	  = newOrt;
			firmsDataAdapter.UpdateCommand.Parameters["Postfach"].Value = newPostfach;
			firmsDataAdapter.UpdateCommand.Parameters["PLZ"].Value    = newPLZ;
			firmsDataAdapter.UpdateCommand.Parameters["Straße"].Value = newStraße;
			firmsDataAdapter.UpdateCommand.Parameters["Tel_Nr"].Value = newTel;
			firmsDataAdapter.UpdateCommand.Parameters["Fax_Nr"].Value = newFax;
			firmsDataAdapter.UpdateCommand.Parameters["Mobil_Nr"].Value = newMobil;
			firmsDataAdapter.UpdateCommand.Parameters["E_Mail"].Value = newMail;			
			firmsDataAdapter.UpdateCommand.Parameters["ID_Firma"].Value = firmID;
			
			if (firmsDataSet.HasChanges())
				MessageBox.Show("Bingo");
			firmsDataSet.WriteXml("FirmsDataSet");

			// hier kommt die Fehlermeldung, vorrausgesetzt das DataSet akzeptiert, das es geändert wurde
			firmsDataAdapter.Update(firmsDataSet, "Firmen");
			
			// dieser Befehl gibt keine Fehlermeldung, sondern aktualisiert die Datenbank 
			//updateCom.ExecuteNonQuery();
		}
	catch ...


Sorry für dieses überlage Post, aber ich hab alles reingehauen, wo der Fehler sein könnte.

P.S.: Alles was mit _ anfängt ist eine Property. Der obige Code ist verteilt über die Klasse des GUIs und eine dazugehörende DB-Anbindungsklasse.

25.03.2005 - 01:46 Uhr

ich schlauberger hab nich gesehen das der Thread verschoben wurde.

Vorab: Danke für jegliche Hilfe.

Ich hab das/die Probleme mittlerweise gelöst.
Zum einen das mit AcceptChanges, und die Parameterzuweisung zu den falschen Commands.
Allerdings geht es in Acces sehrwohl mit den Fragezeichen.

Aber zu meinem Problem mit dem Parametern, und wann sie einen Wert bekommen. So ganz ist mir das noch nicht klar, und da meine letze Frage wohl etwas kryptisch war, versuche ich es nochmal.

Ich habe ein update command, für das ich 3 Parameter habe.


OdbcCommand updProjekte = new OdbcCommand();
updProjekte.Connection  = myConnection;
updProjekte.CommandText = "UPDATE Projekte SET BV_Name = ?, BV_Nr = ? " + 
"WHERE ID_Projekt = ? ";			
updProjekte.Parameters.Add("BV_Name", OdbcType.VarChar);
updProjekte.Parameters.Add("BV_Nr", OdbcType.VarChar);

// Parameter zur Identifizierung des Datensatzes in der Datenbank
p = new OdbcParameter("ID_Projekt", OdbcType.Int);
p.SourceVersion = DataRowVersion.Original; 
updProjekte.Parameters.Add(p);

Soweit so gut.

So, wie kommen nun meine geänderten Werte in die Parameter?
Mein DataSet wird mit den neuen Werten aktualisiert:


if (CheckValues( bv_Name, bv_Nr))
{
	this.bv_Name = bv_Name;
                this.bv_Nr	= bv_Nr;
	
	DataRow newRow;
	try
	{
	         newRow = myDataSet.Tables["Projekte"].NewRow();
	         newRow["BV_Name"] = bv_Name;
	         newRow["BV_Nr"]   = bv_Nr;
                         myDataSet.Tables["Projekte"].Rows.Add(newRow);	
	}
	catch(System.ArgumentException ex)
	{
		MessageBox.Show(ex.Message, "Fehler beim hinzufügen der neuen Zeilen...");
}

Wenn ich nun DataAdapter.Update(myDataSet) aufrufe, müsste dann der DataAdapter nicht erkennen, welche Werte im DataSet sich geändert haben, und dementsprechend in die 3 Platzhalter oben im Updatecommand die neuen Werte einsetzen?
ODer muss ich das nochmal explizit machen?

Momentan funktioniert das bei mir so (und es geht):



DataAdapter.InsertCommand.Parameters["BV_Name"].Value = this.bv_Name;
DataAdapter.InsertCommand.Parameters["BV_Nr"].Value   = this.bv_Nr;
DataAdapter.Update(myDataSet, "Projekte");
myDataSet.AcceptChanges();


aber könnte ich mir diese Zuweisung der Parameter Values (also deren Inhaltes) nicht sparen?

24.03.2005 - 16:43 Uhr

am besten in der MSDN nach ODBC suchen , und allem was dazu gehört.
Die C# Datenbank Klassen mit einem Odbc im Namen (bzw. am Anfang) sind u.a. zuständig für Access Datenbanken.
Die meisten Bücher (Tutorials als solche kenne ich gerade keines) beschreiben lieber immer, wie es mit dem Visual Studio (also zusammenklicken) geht.

Davon kann ich aber nur abraten.
Bestenfalls aus so einem Buch das Grundverständniss holen ( also welche Klasse brauche ich wozu), und dann zum Bsp. per MSDN ausprobieren.

Solltest du was anderes als Access nehmen, ändern sich (grösstenteils) nur die Klassennamen, dann heisst das ganze nicht OdbcConnection sondern SQLConnection etc...

Welches Buch mir recht gut gefällt (is aber im Buch leider alles in VB, nur auf CD auch alles in C#) ist "ADO.NET- Grundlagen und Profiwissen", weil dort eigentlich alles unabhängig von Visual .Net erklärt wird (vor allem die Code Beispiele auf der CD sind "per Hand" gemacht). Das Buch ist von Detlev und Lothar Wanzke, aus dem Hanser Verlag, ISBN 3-446-22157-3.

Vieleicht gibt davon ja auch eine Online Version...

23.03.2005 - 10:19 Uhr

Hallo zusammen!

Ich habe das Problem, das bei meiner Datenbankanwendung zwar alle meine Änderungen im DataSet übernommen werden ( ich sehe sie wenn ich mir den Inhalt des DataSet angucke), aber sie kommen nicht in der Datenbank an.
Ich weiss das ich die Update() Methode des DataAdapters aufrufen muss ( und vorher die AcceptChanges() des DataSets). Desweiteren hat mein Adapter Insert und Update Commands ( selbstgemacht, nicht mit dem Commandbuilder).
Aber egal wie mein Insert Command aussieht, nix kommt in der DB an.

Deshalb, bevor ich den Code poste, die eher allgemeine Frage:
Gebe ich einem DataAdapter immer ein SQL-Command mit Parametern, die dann sofort auch spezifieziere ( also welche Typ, welche Tabelle etc...), aber niemals selber mit Werten belege? Der DataAdapter erkennt doch beim Aufruf der Update Methode doch von alleine, welche Einträge sich geändert haben, und nur die werden dann geändert.
Setzt er dann von sich aus die Werte in die Parameter-Platzhalter im SQL Command?
Eigentlich hab ich schon "alles" versucht. Den SQL String per Konkatenation mit den Variablen selbst "zusammenstecken", die Parameter da übergeben wo die entsprechenden Werte bekannt sind, oder halt keine Parameter übergeben. Nix funzt.

Vorab: Ich schreib in C# eine Anwendung mit einer Access DB.

hier die Initialisierung meines DataAdapters:

P.S.: Ja ich bin ein ziemlicher Anfänger und hab gleichzeitig recht viel Druck das mein Programm endlich läuft


projekteAdapter = new OdbcDataAdapter(); 

OdbcCommand insProjekte = new OdbcCommand(); 
insProjekte.Connection       = myConnection; 
insProjekte.CommandText  = "INSERT INTO Projekte ([BV_Name], [BV_Nr]) VALUES (?,?)"; 
          
insProjekte.Parameters.Add("[BV_Name]", OdbcType.Text, 50); 
         insProjekte.Parameters.Add("[BV_Nr]", OdbcType.Text, 50); 

OdbcCommand updProjekte = new OdbcCommand(); 
updProjekte.Connection       = myConnection; 
updProjekte.CommandText = "UPDATE Projekte SET [BV_Name] = ?, [BV_Nr] = ? "; 

insProjekte.Parameters.Add("[BV_Name]", OdbcType.Text, 50); 
insProjekte.Parameters.Add("[BV_Nr]", OdbcType.Text, 50);

und hier der Aufruf der Update-Methode:


myDataSet.AcceptChanges(); 
erGOPausen2.MainInstance._ProjekteAdapter.InsertCommand.Parameters["[BV_Name]"].Value = bv_Name; 
erGOPausen2.MainInstance._ProjekteAdapter.InsertCommand.Parameters["[BV_Nr]"].Value   = bv_Nr; 
erGOPausen2.MainInstance._ProjekteAdapter.Update(myDataSet, "Projekte");

wie gesagt, diese Belegung der Parameter ist eine von vielen Versuchen, die ich hinter mir habe.
Und ich bekomme keine Fehlermeldung...
Es kommt einfach nix in der DB an...

Bin für jede Hilfe SEHR dankbar!!