Autor Beitrag
rittergig
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 33



BeitragVerfasst: Di 05.07.11 09:47 
Ich führe folgendes durch:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
DBntities context = new DBntities();

User u = new User();

// do something else

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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 157
Erhaltene Danke: 19

Win XP
C#, Fortran 95 - Visual Studio
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 33



BeitragVerfasst: Di 05.07.11 10:11 
user profile icongfoidl hat folgendes geschrieben Zum zitierten Posting springen:
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):
ausblenden C#-Quelltext
1:
2:
3:
DBEntities c = new DBEntities();
User u = new User("Max Müller");
c.SaveChanges();

user profile icongfoidl hat folgendes geschrieben Zum zitierten Posting springen:
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 222
Erhaltene Danke: 16

Win XP, Win 7 64-Bit
C# 4.0 (VS2010)
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 157
Erhaltene Danke: 19

Win XP
C#, Fortran 95 - Visual Studio
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 33



BeitragVerfasst: Di 05.07.11 14:10 
user profile icongfoidl hat folgendes geschrieben Zum zitierten Posting springen:
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.


user profile icongfoidl hat folgendes geschrieben Zum zitierten Posting springen:
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:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
public partial class User
{
  /// <summary>
  /// Initialisiert eine neue Instanz der <see cref="User"/> Klasse.
  /// </summary>
  public User(string name)
  {
    this.Name = name;
  }
}


user profile icongfoidl hat folgendes geschrieben Zum zitierten Posting springen:
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:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
// Variante 1
DBEntities c = new DBEntities();
User v = new User();
c.SaveChanges(); //-> kein Wert wird hinzugefügt

// Variante 2
DBEntities c = new DBEntities();
User v = new User("Max Mustermann");
c.AddToUsers(v);
c.SaveChanges(); //-> 1 Wert wird hinzugefügt

// Variante 3
DBEntities c = new DBEntities();
User v = new User("Max Mustermann");
//c.AddToUsers(v);
c.SaveChanges(); //-> 1 Wert wird hinzugefügt

// Variante 4
User v = new User("Max Mustermann");
DBEntities c = new DBEntities();
c.SaveChanges(); //-> kein Wert wird hinzugefügt
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 222
Erhaltene Danke: 16

Win XP, Win 7 64-Bit
C# 4.0 (VS2010)
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 157
Erhaltene Danke: 19

Win XP
C#, Fortran 95 - Visual Studio
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 178
Erhaltene Danke: 21



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 222
Erhaltene Danke: 16

Win XP, Win 7 64-Bit
C# 4.0 (VS2010)
BeitragVerfasst: Di 12.07.11 13:11 
partial heißt nur, dass die Klasse verteilt sein kann.

Bsp:

ausblenden 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:

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 178
Erhaltene Danke: 21



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 222
Erhaltene Danke: 16

Win XP, Win 7 64-Bit
C# 4.0 (VS2010)
BeitragVerfasst: 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.