Autor |
Beitrag |
rittergig
      
Beiträge: 33
|
Verfasst: Di 05.07.11 09:47
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
      
Beiträge: 157
Erhaltene Danke: 19
Win XP
C#, Fortran 95 - Visual Studio
|
Verfasst: 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ü
_________________ Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!
|
|
rittergig 
      
Beiträge: 33
|
Verfasst: Di 05.07.11 10:11
|
|
norman2306
      
Beiträge: 222
Erhaltene Danke: 16
Win XP, Win 7 64-Bit
C# 4.0 (VS2010)
|
Verfasst: 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
      
Beiträge: 157
Erhaltene Danke: 19
Win XP
C#, Fortran 95 - Visual Studio
|
Verfasst: 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ü
_________________ Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!
|
|
rittergig 
      
Beiträge: 33
|
Verfasst: 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
      
Beiträge: 222
Erhaltene Danke: 16
Win XP, Win 7 64-Bit
C# 4.0 (VS2010)
|
Verfasst: 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
      
Beiträge: 157
Erhaltene Danke: 19
Win XP
C#, Fortran 95 - Visual Studio
|
Verfasst: 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ü
_________________ Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!
|
|
dark-destination1988
      
Beiträge: 178
Erhaltene Danke: 21
|
Verfasst: 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
      
Beiträge: 222
Erhaltene Danke: 16
Win XP, Win 7 64-Bit
C# 4.0 (VS2010)
|
Verfasst: 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
      
Beiträge: 178
Erhaltene Danke: 21
|
Verfasst: 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
      
Beiträge: 222
Erhaltene Danke: 16
Win XP, Win 7 64-Bit
C# 4.0 (VS2010)
|
Verfasst: 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.
|
|