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)
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!"
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)
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!"
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)
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.
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!"
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)
Wenn ich
ziel
mittelsziel = 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. 🤔
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
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)
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.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
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)
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)
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.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
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!"