Ich versuche, die gesamte MVC / EF-Beziehung zu verstehen. Wenn ich ein Entity-Modell erzeuge, das nur mit der Datenbank interagiert (da Sie das Entity-Modell nicht an eine View übergeben sollten), dann eine Klasse für das Model und schließlich ein View-Modell, wie unten gezeigt. Meine einzige Frage ist, dass es überflüssig scheint, die zweite Klasse zu haben. Die einzige Ausnahme in den Beispielen, die ich gesehen habe, ist, dass sie Datenanmerkungen auf diese Klasse anwenden, da sie mit der Ansicht interagiert. Warum ist es so wichtig sicherzustellen, dass Entitätsobjekte auf der Ansichtsebene nicht verfügbar sind?
Ich habe noch nicht angefangen, ein Projekt zu schreiben, aber ich gehe davon aus, dass Sie das Entity-Modell für die Interaktion mit einer Datenbank verwenden und es dann in ein ProductModel umwandeln, um zur Ansicht zu gelangen. Ist das die richtige Logik?
Entitätsmodell:
%Vor%Modell:
%Vor%ViewModel:
%Vor%UPDATE:
In dem Beispiel, das ich gelesen habe, haben sie auch einen DBContext gesetzt wie folgt. Ist die ProductModel-Klasse dann nutzlos?
%Vor%Es gibt Zeiten, und besonders bei einfachen Modellen, wo ein Ansichtsmodell möglicherweise nicht benötigt wird. Aber, und ein großes "Aber", ich habe sehr wenige Fälle dieser Situation gefunden und selbst dann finde ich später generell ein Bedürfnis, zurückzugehen und trotzdem ein Ansichtsmodell zu erstellen. Ein spezialisiertes Betrachtungsmodell ist sicherer, einfacher und einfacher rundum.
Sie könnten es als zusätzliche Arbeit betrachten, aber denken Sie daran in Bezug auf die Trennung von Bedenken (was der ganze Sinn von MVC ist). Wenn ich beispielsweise eine SelectList für eine Eingabe bereitstellen möchte, kann ich sie entweder zu ViewBag oder zu meinem Modell hinzufügen. Wenn ich es zu ViewBag hinzufüge, verliere ich die starke Typisierung, was niemals ideal ist, aber es gehört auch nicht zu meiner datenbankverfolgten Entität. Mit einem View-Modell lassen Sie mich diese Information genau dorthin bringen, wo sie hingehört: ein stark typisiertes Modell, das existiert, um die Ansicht zu bedienen und nur um die Ansicht zu bedienen.
Oder prüfen Sie die Validierung: Was ist, wenn ein Feld für die Datenbank erforderlich ist (nicht null), aber ich möchte dies für den Benutzer optional machen und es hinter den Kulissen selbst mit Geschäftslogik füllen, wenn der Benutzer sich entscheidet nicht angeben. Das Ansichtsmodell kann diese Abstraktion leicht handhaben, während das Hinzufügen zu der Entität selbst eine riesige Komplexitätsschicht hinzufügen würde.
Natürlich ist nichts erforderlich. Sie können Ihr Projekt immer so einrichten, wie Sie es möchten, aber Best Practices sind Best Practices aus einem bestimmten Grund: Entwickler wie Sie sind immer wieder auf dieselben Probleme gestoßen und haben sich zu einer praktikablen Lösung zusammengeschlossen. Vielleicht können Sie die Ansichtsmodelle für eine gewisse Zeit vermeiden, aber irgendwann werden Sie auf die gleichen Hindernisse stoßen und sie trotzdem integrieren, also tun Sie es gleich von Anfang an und machen Sie Ihr Leben leichter.
Es gibt zwei Hauptgründe, warum ich eine Modellklasse, getrennt von meiner Entität, erstelle.
Wie Sie bereits erwähnt haben, Attribute. Möglicherweise möchten Sie Ihre Entitäten in mehreren Anwendungen wiederverwenden und sie dürfen nicht dieselben Attribute verwenden. Sie wollen Ihre Entitäten nicht mit diesen verschmutzen.
Je nach ORM benötigen Ihre Entitäten möglicherweise eine Basisklasse. Oder es gibt Attribute oder andere Anpassungen, die Sie auf die Entitäten anwenden müssen. Dies könnte zu Schwierigkeiten beim Testen Ihrer Geschäftslogik führen. Wenn Sie ORMs oder etwas in Ihren ORM-Änderungen ändern, behalten Sie diese Änderung außerdem isoliert vom Rest der Anwendung.
Grundsätzlich isolieren Sie die verschiedenen Ebenen Ihrer Anwendung und schützen eine Ebene vor Änderungen, die in einer anderen Ebene vorgenommen wurden.
Sie benötigen Product class
, ProductViewModel class
und dann Ihre DbContext
.
Wenn Sie dies zum ersten Mal tun, lesen Sie Pro ASP.NET MVC 3 Framework, dritte Ausgabe
oder
Sie haben eine detaillierte Information über MVC und beide Bücher haben einen Real Application tutorial you can follow
von Anfang bis Ende einschließlich der Bereitstellung.
Sie erfahren auch etwas über Unit Testing und andere MVC-Tools wie Dependency Injection (Ninject) und Moq
Zusätzlich zu den obigen Antworten wurde noch ein weiterer Punkt erwähnt, der verhindern soll, dass Daten an die Ansicht / den Client gesendet werden, die nicht benötigt werden.
Nehmen Sie zum Beispiel an, dass Ihr Produktmodell den Preis enthält, den Sie Ihrem Lieferanten zahlen, um das Produkt zu kaufen. Sie möchten nicht, dass Ihre Kunden diese Daten sehen, aber wenn sie im Modell enthalten sind, das an die Ansicht gesendet wird - auch wenn Sie dieses Feld nicht anzeigen - können sie es beurteilen. In diesem Fall würden Sie ein anderes Ansichtsmodell verwenden und die Daten aus dem ef / datenbankmodell in das Ansichtsmodell kopieren, bevor Sie es an die Ansicht senden.
Manchmal können Sie mit einer DBcontext-Klasse, einer EF / Datenbank-Klasse / Model und mehreren Viewmodels enden, die jeweils eine andere Teilmenge der Daten aus dem Datenbankmodell enthalten.
Sie können sich auch mit einem Viewmodel finden, das Daten von mehreren Datenbankmodellen enthält. Sie sehen, dass die Ansicht Listen oder Dropdowns als Alternative zum Senden der Listenoptionen im Viewbag verwendet.
Das ViewModel wird das sein, was tatsächlich an den / aus dem Browser übergeben wird, oft über JSON, wenn Sie etwas erstellen, das vor Ort aktualisiert / gespeichert werden kann. Also:
ASP.Net MVC hat einige Einschränkungen hinsichtlich dessen, was es über JSON erzeugen / verbrauchen kann (und seine Beschränkungen unterscheiden sich geringfügig in jeder Richtung); Sie können ein ViewModel verwenden, um das zu umgehen
Die Größe der Daten, die Sie aus der Datenbank zurückholen, ist möglicherweise nicht die, die zum Browser gelangen muss - Sie müssen z. B. einige zusätzliche Felder zurückziehen und überprüfen, bevor Sie sie weitergeben, aber nur wollen um eine Teilmenge weiterzugeben - das ViewModel ist die Teilmenge.
Einige natürliche Strukturen in JSON sind in einer Datenbank nicht wirklich verfügbar - Sie könnten beispielsweise das Äquivalent eines in Ihrem Modell gespeicherten Dictionary haben, beispielsweise eine Tabelle mit einigen Werten und eine andere Tabelle mit einem FK-Zeiger zurück zu ihm, eine Id, und ein String-Wert - aber für den Browser, um es zu nutzen, brauchen Sie vielleicht nur diesen String-Wert. Im ViewModel repräsentieren Sie das alles mit einem einfachen Dictionary (das als einfaches JS-Objekt auf dem Client endet).
Oft sind Dinge wie Datumsformatierung auf dem Client schwach oder schwach, abhängig davon, ob der Client eine genaue Systemuhr hat usw. Ich verwende häufig einen String in meinem ViewModel, in dem ich eine DateTime in meinem Model habe UTC in ihre Zeitzone und formatiere sie auf dem Server, bevor sie in ihrem Browser ankommt.
Manchmal müssen Sie Teile des Modells dem Browser aussetzen. Wenn Sie beispielsweise in einem System die Zeilen-ID dem Browser zur Verfügung stellen, können Sie ein Sicherheitsrisiko erzeugen. Ein ViewModel macht es einfach, Teile Ihres Modells auszublenden.
Siehe auch: zum Entwerfen von ViewModel
Um zu beginnen, gibt es etwas, das fehlt und kombinierte Techniken, eins ist, vollständig die DAL von allen anderen Schichten zu abstrahieren, das ist eine Technik. Aber es gibt auch andere Techniken, die verwendet werden können; Verwenden Sie die Klassen "Entities" als Domänenklassen. In einem einfachen Szenario verwenden wir immer die Domänenklassen auf der Business-Schicht, um alle Geschäftsregeln anzuwenden. Dies wird uns sehr dabei helfen, die Testbarkeit durch Layer zu kombinieren und unnötige Links zwischen Layern zu vermeiden, ohne viele Codezeilen / Klassenzahlen zu erhöhen.
Auch dieser Ansatz, um diese Domänenobjekte (Domänenklassen) über alle Ebenen zu haben, wird Ihnen die Arbeit mit MVC erheblich erleichtern, da diese Klassen Datenannotationen haben können, die von:
verwendet werdenUm auch das Konzept und die Verwendung dieser Art von Klassen zu verstehen, müssen wir etwas beachten. Wenn wir POCOs als unsere Entitäten und Domänenklassen verwenden, sind dieselben Klassen nicht dieselben Klassen, die Entity Framework bei der Interpretation von Abfragen an die Datenbank verwendet. Stattdessen erstellt EF dynamische Klassen (abgeleitet vom POCO), die dieses Domänenobjekt als eine Entität darstellen und alle virtuellen Felder laden, typischerweise die zugehörigen Entitäten.
Und Sie werden Code von Klassen und triviale Neuzuordnung speichern.
Hoffe, das hilft
Warum ist es so wichtig sicherzustellen, dass Entitätsobjekte nicht auf der Ansichtsebene verfügbar sind?
Es ist nicht. Für einen einfachen CRUD-Controller ist es oft einfacher, das Entitätsobjekt einfach zu übergeben. Für eine komplexere Seite können Sie mit mehr als einem Entity-Objekt / -Typ gleichzeitig interagieren. Wie würden Sie Informationen über beide Objekte weitergeben, ohne eine neue Modellklasse zu erstellen?
Tags und Links asp.net-mvc c# entity-framework