Laden...

GetChangeset().Update.Count ist immer 0

Erstellt von HeikoAdams vor 6 Jahren Letzter Beitrag vor 6 Jahren 2.147 Views
HeikoAdams Themenstarter:in
62 Beiträge seit 2017
vor 6 Jahren
GetChangeset().Update.Count ist immer 0

verwendetes Datenbanksystem: MS SQL 2014

Hallo,
in meiner Anwendung habe ich folgenden Code, der prüft, ob Datensätze angelegt oder aktualisiert werden müssen:


int auflage2 = TryParseInt(auflage);
ziel = dataContext.VDDArtikeldaten.SingleOrDefault(import => import.ProduktID == produktId && import.Auflage == auflage2);
updating = ziel.IsNotNull();

if (!updating)
{
   progress.Mode = FormProgress.Modes.Insert;
   ziel = new VDDArtikeldaten();
}
else
{
   progress.Mode = FormProgress.Modes.Update;
   this.AddLogEntry(string.Format(Properties.Resources.UPDATE_DATASET, produktId));
}

Wenn ich jetzt beim Aktualisieren meine Felder befüllt habe und vor dem SubmitChanges des DataContext mir GetChangeset().Update.Count des DataContext ausgeben lasse, steht da immer 0 drin. Mache ich etwas falsch??

Wer ordentlichen Code schreibt, lebt entspannter 8)

6.911 Beiträge seit 2009
vor 6 Jahren

Hallo HeikoAdams,

kannst du bitte noch beschreiben die dein Modell aussieht? Ich sehe nichts od. übersehe ich es. Im else-Zweig wird nicht auf ziel zugegriffen, das verwirrt mich deshalb.

Du kannst im Modell auch einen Breakpoint beim Getter/Setter der Eigenschaften setzen um zu schauen ob die Werte überhaupt geändert werden.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

HeikoAdams Themenstarter:in
62 Beiträge seit 2017
vor 6 Jahren

HIm else-Zweig wird nicht auf ziel zugegriffen, das verwirrt mich deshalb. ziel wird ja auch in der 2. Zeile gefüllt und anschließend auf NULL geprüft. Deshalb wird es im Else-Zweig nicht verwendet 😉

Was genau meinst Du mit Modell?

Wer ordentlichen Code schreibt, lebt entspannter 8)

6.911 Beiträge seit 2009
vor 6 Jahren

Hallo HeikoAdams,

ziel wird ja auch in der 2. Zeile gefüllt und anschließend auf NULL geprüft. Deshalb wird es im Else-Zweig nicht verwendet 😉

😉 soweit konnte ich dem Code schon folgen.

Ja aber wo erwartest du eine Aktualisierung von ziel welche der DataContext mitbekommen soll?

Im if-Zweig wird der ziel-Variablen eine neues Objekt zugewiesen und das kennt der DataContext nicht, wie auch. Er kennt nur das Objekt, auf das vorher die ziel-Variable verwiesen hat.

Im else-Zweig passiert gar nichts mit ziel.

Wenn du im if-Zweig eine Eigenschaft von ziel änderst (und kein neues Objekt ziel zuweist), so wird auch eine Änderung angezeigt.

Klar?

Mit Modell meine ich den Datenkontext, aber das ist jetzt nicht mehr nötig.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

HeikoAdams Themenstarter:in
62 Beiträge seit 2017
vor 6 Jahren

Okay, jetzt hab ich es.

Die Felder werden an einer anderen Stelle im Code nach dem Muster ziel.SPALTE = neuerWert befüllt. Wenn ich mir danach GetChangeset().Update.Count augeben lasse, hat es immer den Wert 0. Oder gibt ein InsertOnSubmit Pendant für Updates, das ich vergessen habe?

Wer ordentlichen Code schreibt, lebt entspannter 8)

D
985 Beiträge seit 2014
vor 6 Jahren

Woher soll denn der DataContext wissen, dass er diese Instanz in ziel überwachen soll, wenn du diese Instanz selber erstellst ziel = new VDDArtikeldaten();?

Riechen kann der noch nicht

Versuche es also mal mit einem dataContext.VDDArtikeldaten.InsertOnSubmit( ziel ); wenn du ein neues Ziel erzeugen musst und dann sollte sich beim ChangeSet auch etwas bei der Inserts Collection tun.

6.911 Beiträge seit 2009
vor 6 Jahren

Hallo HeikoAdams,

Okay, jetzt hab ich es.

Hm, dann wundert mich warum die immer noch mit 0 herumkämpfst.

Vllt macht es das Beispiel klarer:


using System.Diagnostics;
using System.Linq;

namespace ConsoleApp1
{
	class Program
	{
		static void Main(string[] args)
		{
			using (DataClasses1DataContext db = new DataClasses1DataContext())
			{
				var kunde = db.Kunden.FirstOrDefault();

				int updateCount = db.GetChangeSet().Updates.Count;
				Debug.Assert(updateCount == 0);

				kunde.Name = "Neuer Name";			// diese Instanz von Kunde wird vom Context verfolgt

				updateCount = db.GetChangeSet().Updates.Count;
				Debug.Assert(updateCount > 0);
			}

			using (DataClasses1DataContext db = new DataClasses1DataContext())
			{
				var kunde = db.Kunden.FirstOrDefault();

				int updateCount = db.GetChangeSet().Updates.Count;
				Debug.Assert(updateCount == 0);

				kunde = new Kunde();               // diese Intanz ist dem Context unbekannt!
				kunde.Name = "Neuer Name";

				updateCount = db.GetChangeSet().Updates.Count;
				Debug.Assert(updateCount == 0);     // da es eben dem Context unbekannt ist, kann er die Änderung nicht verfolgen
			}
		}
	}
}

[Tutorial] Vertrackte Fehler durch Vergleich von echtem Projekt mit minimalem Testprojekt finden kann dabei auch helfen.

gibt ein InsertOnSubmit Pendant für Updates, das ich vergessen habe?

Bei Insert wäre es die Inserts-Eigenschaft von ChangeSet. Cf. ChangeSet Class | Microsoft Docs

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

HeikoAdams Themenstarter:in
62 Beiträge seit 2017
vor 6 Jahren

Ihr habt da irgendwas falsch verstanden.

Wenn ich ziel mittels ziel = new VDDArtikaldaten() initialisiere und dann die einzelnen Feldder befülle, hat GetChangeset vor dem SubmitChanges korrekte Werte (Insert.Count > 0).

Wenn ich ziel aber per ziel = dataContext.VDDArtikeldaten.SingleOrDefault(import => import.ProduktID == produktId && import.Auflage == auflage2); initalisiere und dann die einzelnen Feldder befülle, hat GetChangeset vor dem SubmitChanges falsche Werte (Updates.Count > 0).

Vielleicht sollte ich noch erwähnen, das VDDArtikaldaten eine per dbml-File autmatisch generierte Klasse ist.

Wer ordentlichen Code schreibt, lebt entspannter 8)

16.827 Beiträge seit 2008
vor 6 Jahren

Wenn ich ziel mittels ziel = new VDDArtikaldaten() initialisiere und dann die einzelnen Feldder befülle, hat GetChangeset vor dem SubmitChanges korrekte Werte (Insert.Count > 0)

Der DataContext überwacht aber keine Objekte, die via new erzeugt werden und nicht aktiv diesem hinzugefügt werden. 🤔

HeikoAdams Themenstarter:in
62 Beiträge seit 2017
vor 6 Jahren

Doch, wenn die VDDArtikaldaten Klasse genau so wie der DataContext per dbml-File generiert wurden.

Aber das ist ja garnicht das Problem. Das Problem ist, wenn ich einen vorhandenen Datensatz ändere und dann speichere, hat GetChangeset.Updates.Count immer 0 als Wert.

Wer ordentlichen Code schreibt, lebt entspannter 8)

16.827 Beiträge seit 2008
vor 6 Jahren

Ah... Du hast also gar keine POCOs... das ist mal gut zu wissen. Die Info war bislang unbekannt. 😉

Wo genau rufst Du denn den Status auf? Vor oder nach SubmitChanges?
Die Code-Stelle fehlt hier.

HeikoAdams Themenstarter:in
62 Beiträge seit 2017
vor 6 Jahren

Die entsprechende Code-Stelle sieht so aus:


internal override void CommitWork(int counter)
{
	int records;

	if (this.IsInsertMode() || this.IsUpdateMode())
	{
		if (this.IsInsertMode())
		{
			records = this.DataContext.GetChangeSet().Inserts.Count;
		}
		else
		{
			records = this.DataContext.GetChangeSet().Updates.Count;
		}

		this.AddLogEntry(string.Format(
			Properties.Resources.SAVE_DATASETS,
			records.ToString()));

		if (this.IsInsertMode() && this.dbItems.Count() != 0)
		{
			this.DataContext.VDDArtikeldaten.InsertAllOnSubmit(this.dbItems);
		}

		this.Mode = Modes.Commit;
		this.DataContext.SubmitChanges();
	}
}

Wer ordentlichen Code schreibt, lebt entspannter 8)

HeikoAdams Themenstarter:in
62 Beiträge seit 2017
vor 6 Jahren

Okay, ich glaube, das Problem hat sich quasi von alleine gelöst. GetChangeset.Update.Count wird anscheinend nur dann erhöht, wenn sich auch tatsächlich Daten geändert haben. Den gleichen Datensatz noch einmal in die Tabelle schreiben lässt den Wert auf seinem aktuellen Wert stehen.

Wer ordentlichen Code schreibt, lebt entspannter 8)

16.827 Beiträge seit 2008
vor 6 Jahren

Gut; hättest auch sagen können, dass sich die Entität gar nicht inhaltlich ändert - denn das erkennt der Kontext durchn die Proxies bei DbFirst. =)

Jede Entity wird getrackt (durch ein Proxy) und jede Entity hat auch einen State.
Ist der State nicht auf Updated kommt die Entity gar nicht erst in das ChangeSet, egal wie oft Du es hinzufügst.
Die Relation besteht ja schon...

Anders würden sich hier Code First mit Pocos verhalten.

6.911 Beiträge seit 2009
vor 6 Jahren

Hallo,

ah, das ist Linq2Sql. Schau dir mal den generierten Code an und dort v.a. die Eigenschaften. Wenn der gleiche Wert zugewiesen wird, macht er dort nichts, daher zeigt es auch keine Änderung, da daraus auch kein UPDATE abgesetzt werden soll.

mfG Gü

PS: Vorhin hab ich aus versehen den Inhalt der Zwischenablage reinkopiert. Da hat mir der Ghosttyper zuviel gemacht. Sorry.

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"