Benutzer mit den meisten Antworten
Entity Framework - zweite Abfrage überschreibt das Ergebnis der ersten

Frage
-
Hallo,
ich glaube ich habe ein Verständnisproblem bezüglich des Entity Framework. Ich habe eine Datenbank in der Personen-Tabelle werden Schüler und Lehrer (Spalten: PrimaryKey, Vorname, Nachname, etc. ) gespeichert werden.
Damit ich die Abfragen nicht immer wieder neue schreiben muss habe ich eine Person_Helper Klasse angelegt, in der ich auf die Funktion GetPersons(Personen personen) zugreifen kann. Diese Funktion liefert mir eine ObservableCollection vom Typ Personen.private ObservableCollection<Persons> _persons = new ObservableCollection<Persons>(); public ObservableCollection<Persons> GetPersons(Persons filter) { _persons.Clear(); _persons.Add(new Persons() { PersonsPK = 0 }); using (DataBase_Model context = new DataBase_Model()) { IQueryable<persons> query = context.Set<persons>().OrderBy(p => p.surname).ThenBy(p => p.firstname); if (!String.IsNullOrEmpty(filter.firstname)) query = query.Where(p => p.firstname.Equals(filter.firstname)); if (!String.IsNullOrEmpty(filter.surname)) query = query.Where(p => p.surname.Equals(filter.surname)); if (filter.isTeacher.HasValue) query = query.Where(p => p.isTeacher == filter.isTeacher); var result = query.ToList<persons>(); if (result != null) new List<persons>(result).ForEach(g => _persons.Add(g)); return _persons; } }
Wenn ich jetzt in einer anderen Klasse eine neue Instanz von Person_Helper aufrufe um einmal eine Liste aller Schüler und einmal eine Liste aller Lehrer abfrage Funktioniert das auch aber die zweite abfrage überschreibt das Ergebnis der der ersten.
Person_Helper personhelper = new Person_Helper(); public ObservableCollection<persons> Teacher {get; set; } public ObservableCollection<persons> Student {get; set; } Teacher = personhelper.GetPersons(new persons() { isTeacher = true}); //Hier stimmt noch die Lehrer liste erst nach dem Student aufruf wird diese überschrieben Student = personhelper.GetPersons(new persons() { isTeacher = false});
Ich vermute mal das ich einen Denkfehler bezüglich des EF habe oder der ObservableCollection - aber ich weiß leider nicht was für einen. Ich könnte natürlich eine zweite Instanz des Person_Helper anlegen und mit der ersten mir die Schüler und mit dem zweiten die Lehrer abfrage.
Ich hoffe Ihr könnt mir auf die Sprünge helfen.Gruß Chris
Antworten
-
Hallo Chris,
da Du das Ergebnis in einer Variablen _persons auf Klassenebene speicherst und dieses bei jeder Abfrage überschrieben wird, ändern sich klarerweise auch deine Variablen Teacher und Student.
Verlege die Variable _persons in die Methode GetPersons, dann passt es.
Anstelle von:
if (result != null) new List<persons>(result).ForEach(g => _persons.Add(g)); return _persons;
kannst Du aber auch:
return new ObservableCollection<Persons>( result );
schreiben. Dann sparst Du dir _persons komplett.
---
P.S.: Deine Benennung ist suboptimal, da Du die Klassen in der Mehrzahl und die List, Collection, ... Variablen in der Einzahl benannt hast.
Die Klasse an sich sollte bspw. Person heißen, die ObservableCollections dann Teachers und Students.
Das kann man im Entity Framework eigentlich relativ gut machen, da man bei der englischen Benennung die Ein- und Mehrzahlnamen automatisch angleichen lassen kann.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
- Bearbeitet Stefan FalzModerator Freitag, 23. Dezember 2016 18:24
- Als Antwort vorgeschlagen Dimitar DenkovMicrosoft contingent staff, Administrator Dienstag, 27. Dezember 2016 11:45
- Als Antwort markiert ELLoro Samstag, 31. Dezember 2016 15:16
Alle Antworten
-
Hallo Chris,
da Du das Ergebnis in einer Variablen _persons auf Klassenebene speicherst und dieses bei jeder Abfrage überschrieben wird, ändern sich klarerweise auch deine Variablen Teacher und Student.
Verlege die Variable _persons in die Methode GetPersons, dann passt es.
Anstelle von:
if (result != null) new List<persons>(result).ForEach(g => _persons.Add(g)); return _persons;
kannst Du aber auch:
return new ObservableCollection<Persons>( result );
schreiben. Dann sparst Du dir _persons komplett.
---
P.S.: Deine Benennung ist suboptimal, da Du die Klassen in der Mehrzahl und die List, Collection, ... Variablen in der Einzahl benannt hast.
Die Klasse an sich sollte bspw. Person heißen, die ObservableCollections dann Teachers und Students.
Das kann man im Entity Framework eigentlich relativ gut machen, da man bei der englischen Benennung die Ein- und Mehrzahlnamen automatisch angleichen lassen kann.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
- Bearbeitet Stefan FalzModerator Freitag, 23. Dezember 2016 18:24
- Als Antwort vorgeschlagen Dimitar DenkovMicrosoft contingent staff, Administrator Dienstag, 27. Dezember 2016 11:45
- Als Antwort markiert ELLoro Samstag, 31. Dezember 2016 15:16
-
Vielen Dank und Entschuldige die späte Rückmeldung ( diese Feiertage :-) ) das hat geholfen. Vielen Dank für den Tipp mit der Klassen Benennungen ich war mit der Bezeichnung auch unglücklich, aber manchmal sieht man den Wald vor lauter Bäumen nicht, oder mit fehlt noch die Übung.
Mir ist zwar noch nicht ganz klar warum die erste Liste von der zweiten Überschrieben wurde, ich rufe doch die Methode der PersonHelper Klasse mit unterschiedlichen Parametern auf und die zurück gegeben Liste bzw. ObservableCollection wird doch in die ObservableCollection von Teacher bzw. von Student übergeben und somit sind das doch zwei unterschiedliche Variablen?
Oder sind das nur Referenzen auf die private Liste in der PersonHelper die Ich über die Methode GetPerson(Person filter) referenziere, dann würde das Überscheiben einen Sinn ergeben. Aber vom Gefühl her passt mir meine Erklärung nicht.....
Vielleicht kannst du mir noch etwas Licht ins dunkle bringen.
Gruß Chris
-
Hallo Chris,
deine zweite Annahme ("nur Referenz") ist richtig. Ich versuch es mal zu erklären:
---
Du hast eine Instanz deiner Helper Klasse "Person_Helper".
Diese wiederum hat eine auf Klassenebene deklarierte Variable "_persons".
Bei jedem Aufruf der Methode "GetPersons" wird die Variable "_persons" geleert und neu befüllt. Am Ende des Methodenaufruf gibst Du "_persons" zurück.
Wahrscheinlich gehst Du davon aus, dass deine Eigenschaften:
public ObservableCollection<persons> Teacher {get; set; } public ObservableCollection<persons> Student {get; set; }
beim jeweiligen Aufruf von GetPersons den zurückgegebenen Wert speichern. Dem ist aber nicht so, es wird letztendlich nur ein Verweis auf das Objekt "_persons" gespeichert. D.h. wenn Du bspw. nach:
Teacher = personhelper.GetPersons(new persons() { isTeacher = true}); Student = personhelper.GetPersons(new persons() { isTeacher = false});
noch ein Element in "Teacher" einfügen würdest, wäre das auch in "Student" enthalten und umgekehrt.
Das Ganze ist natürlich erheblich komplexer, das zu erklären, würde aber den Rahmen des Forums bei weitem sprengen. Lies dich dazu mal in Wertetypen und Referenztypen ein. Das wird für deine weiteren Schritte noch ziemlich wichtig :)
Eine kurze aber IMHO auch passende Erklärung findest Du bspw. hier:
Referenz- und Wert-Typen: Was ist der Unterschied in .NET?
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community- Als Antwort vorgeschlagen Stefan FalzModerator Freitag, 30. Dezember 2016 17:08