Entity Framework und MVVM
-
Hallo zusammen.
Habe zwar schon einiges im Netz gefunden zu meinem Thema. Aber ich habe noch nicht die Antwort auf meine Frage gefunden. Darum möchte ich gerne euch fragen:
Ich bin dabei eine WPF Applikation mit MVVM und dem EntityFramework aufzubauen. Hier muss man dazu sagen dass ich zwingend auf das .Net 3.5 Framework und somit auch auf das EntityFramework 3.5 festgelegt bin.
Aus verschiedenen Gründen möchte ich nun nicht die Objekte die ich vom EntityFramework erhalte als Models für mein MVVM verweden sondern ein Mapping dazwischen schalten.
Nun habe ich eine Klasse implementiert die mir die Objekte aus der Datenbank holt und mir dann meine entsprechenden Modelle aus den EF Objekten generiert.
Ich würde dies als mein Repository ansehen.Nun stellt sich mier hier aber die Frage wie ich hier meine Modelle am besten erzeuge.
Unter den Objekten bestehen Beziehungen.
Wenn ich beispielsweise eine Person habe beinhaltet diese eine Adresse. Eine Person kann nun wiederum zu einem Verein gehören usw.
Im Entityframework besitzt nun eine Person eine Referenz zu einer Adresse. Beinhaltet die Klasse "PersonModel" für das MVVM nun auch eine Referenz zu "AdressModel" oder nur die ID zur Adresse wie in der Datenbank auch.
Praktisch wäre es ja schon wenn es eine Referenz enthalten würde. Aber wie ich das ganze anstelle weiß ich nicht.
Also wenn ich mir zum Beispiel erst alle Adressen ausgeben lasse, würde ich mir zunächst alle "AdressModel" erzeugen.
Wenn alle Personen abfrage müßte ich beim erzeugen von "PersonModel" die Referenz zur vorherigen erzeugten "AdressModel" geben lassen oder erzeugen wenn es das AdressModel noch nicht gibt.
Das wäre doch aber das gleiche was EF schon macht und ich würde dann alles dopelt machen.
Ich seh vor lauter Bäumen den Wald nicht
Hoffe ihr könnt mir vieleicht etwas Licht ins Dunkle bringen.
-
y-vonne schrieb:
Wenn ich beispielsweise eine Person habe beinhaltet diese eine Adresse. Eine Person kann nun wiederum zu einem Verein gehören usw.
Die erste Frage die sich stellt: Brauchst du immer alle Verweise? (Im Regelfall bei mir: Nein).
Ich kann nur raten eine möglichst lose Kopplung zu verwenden. Dies muss nicht heißen das man Grundsätzlich nur mit Ids arbeitet, ich würde Ids und Referenzen aber mindestens gleichwertig (und optional) anbieten. Sprich: Sofern du in dem Fall keine Referenz hast, nimmst du die Id, sonst die Referenz (Hat auch den Vorteil das man nicht alle Referenzen benötigt, wenn man nur wenige Teilaspekte betrachtet).
Ich hatte vor kurzen eine Veranstaltung besucht, bei der auch die Performance mit EF angesprochen wurde, und auch dort wurde gesagt das man immer auch die Id anbieten sollte, da man sonst für Änderungen ggf. die verbundenen Objekte mitladen muss.
y-vonne schrieb:
Praktisch wäre es ja schon wenn es eine Referenz enthalten würde. Aber wie ich das ganze anstelle weiß ich nicht.
Ich würde wie gesagt sowohl eine Property mit der Id als auch der Referenz anbieten. Wenn du in einem Szenario bist, bei dem die Referenz gesetzt ist, verwendest du sie entsprechend, sonst die Id.
In etwa so:
class B { public int Id { get; set; } } class A { private int idB; private B b; public int IdB { get { if(b != null) return b.Id; return idB; } set { if(IdB == value) return; if(b != null) b = null; idB = value; } } public B B { get { return b; } set { if(b == value) return; b = value; idB = b != null ? b.Id : 0; } } }
Hier wäre die Referenz von A auf B nicht verpflichtend.
-
Hallo
Wenn du mit dem EF-Framework direkt arbeitest dann bekommst du 2 Properties an dein PersonModel, und zwar eins in dem deine ID zum "AddressModel" hinterlegt ist, sowie ein 2tes, mit dem du direkt auf das AddressModel zugreifen kannst und auf seine Parameter.
Je nach Einstellung (LazyLoading) wird das AddressModel bei Bedarf nachgeladen (LazyLoading = true) oder direkt mitgeladen (LazyLoading = false).
Und nebenbei ist es möglich, das EF-Framework mit sogenannten POCO-Klassen (Plain Old CLR Object) arbeiten zu lassen, dafür gibt es einige Bespiele im Netz. So hab ich es bei meinem letzten Projekte gemacht um das ganze einfach per Unit-Tests überprüfen zu können, da man sich dann selbst eine Schnittstelle baut, diese ableitet und die aufrufe ans EF weiterreicht und eine 2te Klasse erzeugt, in der man eben passende Test-Daten zurückliefert.
MfG Marco
PS: Lass dich nicht abschrecken, es gibt viele die die Umwandlung von EF auf POCO per Hand tun, aber es gibt auch einen POCO Generator, durch denn dann nur noch die POCO-Objekte direkt aus dem VS genieriert werden.
-
Dank euch mal für eure Antwort auch wenn Sie mir noch nicht ganz sonderlich viel gebracht haben.
@asc. Ich weiß schon wie die Klassen auszusehen haben. Das Problem ist aber wie ich die Objekte davon erzeuge.
Ich müßte ja zunächst mal alle Daten laden und alle Klassen erzeugen. Und das ist ja nicht gerade effizient.
@Marc-O : Ich weiß dass es POCO gibt. Allerdings erst ab .Net 4.0. Habe aber gesagt dass ich zwingend auf .Net 3.5 festgelegt bin
-
y-vonne schrieb:
@asc. Ich weiß schon wie die Klassen auszusehen haben. Das Problem ist aber wie ich die Objekte davon erzeuge.
Ich müßte ja zunächst mal alle Daten laden und alle Klassen erzeugen. Und das ist ja nicht gerade effizient.
Laut deiner eigenen Aussage bin ich mehr oder weniger davon ausgegangen das du ohnehin eine Umwandlung vornimmst:
y-vonne schrieb:
Aus verschiedenen Gründen möchte ich nun nicht die Objekte die ich vom EntityFramework erhalte als Models für mein MVVM verweden sondern ein Mapping dazwischen schalten.
Zumal du eben nicht alle Daten laden solltest, sondern nur die in dem Szenario nötigen (In meinen Beispiel wären die Referenzen optional - Nur wo du definitiv die Referenzen brauchst, solltest du diese auch initialisieren, ansonsten sind Ids wesentlich besser).
-
Hallo
Ich hab gelesen, das du mit 3.5 läufst, ich war mir aber auch sicher, das POCO für 3.5 funktioniert. Die einzige Einschränkung ist, das du VS2010 und kein VS2008 hast, welches du nicht definiert hast. Weil siehe hier: http://sqlpractice.wordpress.com/2010/03/30/entity-framework-poco-template-mit-net-3-5/
Die einzige Möglichkeit ist, die IQueryable Schnittstelle richtig bereitstellen, das die Umwandlung so spät wie möglich durchführen kannst, weil einzelne Funktionen, in dennen du die Bedingung übergibst, und die dir dann die gwandelt Objekte zurückgibst, willst du ja bestimmt nicht.
Ein anderen Ansatzs wäre, indem du in den Abfragen mit den Orignal-Objekten arbeitest, und eine Extension bereitstellst, die du noch anhängen kannst um die Umwandlung dann durchzuführen.
Als weitere Möglichkeit wäre noch Linq2Sql zu nennen, aber dann verwendest du eben kein EF mehr, sondern kannst alles selbst per Klassen erzeugen.
Fazit: Die Umwandlung musst du immer per Code den du von Hand schreibst vornehmen.
MfG marco
PS: Und ja ich hab es häufig, das das Zielframework ein niedriegeres als 4.0, was des VS2010 unterstütz, benutzten muss, aktuell arbeite ich an einen Projekt mit 2.0.