Entwickler-Ecke
Datenbanken (inkl. ADO.NET) - Verständnisproblem: Hinzufügen von Objekten zum EF-Context
rittergig - Di 05.07.11 09:47
Titel: Verständnisproblem: Hinzufügen von Objekten zum EF-Context
Ich führe folgendes durch:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7:
| DBntities context = new DBntities();
User u = new User();
context.SaveChanges() |
Ich wundere mich, warum der User u zur Datenbank hinzugefügt wurde.
Ich habe
nicht explizit:
context.AddToUsers(u) geschrieben.
Warum wurde der Nutzer dennoch hinzugefügt?
Ich möchte ihn erstmal erstellen und dann nur bedingt hinzufügen.
Geht das nicht?
Grüße Peter
gfoidl - Di 05.07.11 10:04
Hallo,
bist du sicher dass es genau dieser User u ist oder doch ein anderer der bereits in der DB ist?
BTW: DBntities implementiert IDisposable -> pack es daher in ein using{...}
mfG Gü
rittergig - Di 05.07.11 10:11
gfoidl hat folgendes geschrieben : |
| bist du sicher dass es genau dieser User u ist oder doch ein anderer der bereits in der DB ist? |
Ja, denn meine DB ist zuvor leer. Allerdings habe ich den User zuvor geändert (im Konstruktor):
C#-Quelltext
1: 2: 3:
| DBEntities c = new DBEntities(); User u = new User("Max Müller"); c.SaveChanges(); |
gfoidl hat folgendes geschrieben : |
| BTW: DBntities implementiert IDisposable -> pack es daher in ein using{...} |
Muss ich dieses IDisposable wirklich explizit aufrufen? Ich dachte darum kümmert sich der Garbage Collector.
norman2306 - Di 05.07.11 12:06
Er sagte, du sollst ein Using verwenden, nicht das du es explizit aufrufen sollst. Sonst kann es dir passieren, dass eine Verbindung offen gehalten wird, was dann bei einem weiteren Aufruf in einer Exeption ended. Gerade bei durchlaufen von Enumerationen oder 'from ... in ... select' Aufrufen, die asynchron sind, passiert das recht schnell. Daher gleich sauber arbeiten. Dann gewöhnt man sich nichts schlechtes an.
gfoidl - Di 05.07.11 13:52
Hallo,
| Zitat: |
Ich dachte darum kümmert sich der Garbage Collector.
|
Ja schon, aber erst wenn er es für angebracht hält. Und das ist nicht deterministisch. Daher ist es besser explizit Dispose aufzurufen (oder implizit via using) denn dann werden die Ressourcen gleich freigegeben. Das soll hier aber nicht das Thema sein, es geht um was anderes ;-)
Das Verhalten ist komsich - irgendwo muss sich ein ungewollter Nebeneffekt im Code eingeschlichen haben. Hast du die Designer-Klassen erweitert? Sonst logge mal die SQL-Staments mit die gegen die DB gesendet werden.
mfG Gü
rittergig - Di 05.07.11 14:10
gfoidl hat folgendes geschrieben : |
| Ja schon, aber erst wenn er es für angebracht hält. Und das ist nicht deterministisch. Daher ist es besser explizit Dispose aufzurufen (oder implizit via using) denn dann werden die Ressourcen gleich freigegeben. |
Ok.
gfoidl hat folgendes geschrieben : |
| Das Verhalten ist komsich - irgendwo muss sich ein ungewollter Nebeneffekt im Code eingeschlichen haben. Hast du die Designer-Klassen erweitert? |
Ja, ich habe die Designerklasse partiell erweitert. Ich habe einen Konstruktor hinzugefügt, der gleich das Objekt mit werten initialisiert.
Meine Klasse sieht wie folgt aus:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| public partial class User { public User(string name) { this.Name = name; } } |
gfoidl hat folgendes geschrieben : |
| Sonst logge mal die SQL-Staments mit die gegen die DB gesendet werden. |
Wie geht das? Im Visual Studio oder im Management Studio?
Folgende Varianten habe ich einzeln zum Testen probiert. Vor jeder Variante habe ich die User-Tabelle wieder gelöscht:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| DBEntities c = new DBEntities(); User v = new User(); c.SaveChanges(); DBEntities c = new DBEntities(); User v = new User("Max Mustermann"); c.AddToUsers(v); c.SaveChanges(); DBEntities c = new DBEntities(); User v = new User("Max Mustermann"); c.SaveChanges(); User v = new User("Max Mustermann"); DBEntities c = new DBEntities(); c.SaveChanges(); |
Mein Fazit: Sobald ich an einem Objekt was ändere wird das durch die Änderungsnachverfolgung erkannt und das Objekt wird dem Kontext hinzugefügt.
Jetzt frage ich micht: Wozu gibt es dann die Methode AddToUsers ?
norman2306 - Di 05.07.11 14:15
Habe das gerade bei mir mal so ausprobiert. Bei mir zeigt sich dieses Verhalten nicht. Hast du den Designer-Code geändert?
gfoidl - Di 05.07.11 15:48
Hallo,
| Zitat: |
Wozu gibt es dann die Methode AddToUsers ?
|
Die ist genau dazu gedacht was (nur) bei dir "automatisch" funktioniert.
Probier mal den Context neu zu erstellen. Sonst probier auch im erzeugten Code einen Haltenpunkt zu setzen wo an den User-Objekten rumgewerkt wird. Ev. muss halt eine Eigenschaft draus gemacht werden - dabei aber den Code nicht neu generieren lassen sonst ist das wieder futsch. Sollte generell nur für Testzwecke verwendet werden. Über den Callstack siehst du dann wo das hinzugefügt wird.
| Zitat: |
Sonst logge mal die SQL-Staments mit die gegen die DB gesendet werden.
|
Suche mal danach ;-)
mfG Gü
dark-destination1988 - Di 12.07.11 10:47
ich vermute eher das es an der partiellen klasse liegt.
den immer wenn der konstruktor der partiellen klasse aufgerufen wird, wird das objekt hinzugefügt
norman2306 - Di 12.07.11 13:11
partial heißt nur, dass die Klasse verteilt sein kann.
Bsp:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| public class TestClass { . . . }
public class TestClass { . . . } |
geht nicht. Aber mit 'partial' geht das:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| public partial class TestClass { . . . }
public partial class TestClass { . . . } |
mfg
dark-destination1988 - Di 12.07.11 14:13
ich meinte damit das obere Beispiel.
Das Objekt wurde genau dann hinzugefügt, wenn der Context existiert hat und der partielle Konstruktor aufgerufen wurde...
norman2306 - Di 12.07.11 15:35
Die Klasse existiert immer. Einen 'partiellen' Konstruktor gibt es nicht. Der Konstruktor einer verteilten Klasse ist eindeutig. Es darf nur eine Konstruktorsignatur in einer partiellen Klasse existieren und erst recht darf eine Funktion sowie nicht partiell sein. Partiell heißt nur, dass der trennbare Code (also einzelne Funktionen/Felder) einer Klasse verteilt sein darf, nicht dass es da Dopplungen gibt oder sonst etwas.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!