Ich bin jetzt wirklich zerrissen zwischen der Verwendung von O / R-Mappern oder einfach dem traditionellen Datenzugriff. Aus irgendeinem Grund, jedes Mal, wenn ich O / R-Mapper hochfahre, quälen und sprechen andere Entwickler über Leistungsprobleme oder wie schlecht sie im Allgemeinen sind. Was fehlt mir hier? Ich betrachte LINQ to SQL und Microsoft Entity Framework. Gibt es eine Grundlage für einen dieser Ansprüche? Welche Art von Dingen muss ich kompromittieren, wenn ich einen O / R-Mapper verwenden möchte. Danke.
Das wird zunächst wie eine unabhängige Antwort erscheinen, aber: Eines meiner Nebeninteressen sind Kampfflugzeuge aus dem Zweiten Weltkrieg. Alle kämpfenden Nationen (USA, Großbritannien, Deutschland, UdSSR, Japan usw.) bauten während des Krieges eine Reihe verschiedener Kämpfer. Einige von ihnen verwendeten Sternmotoren (P47, Corsair, FW-190, Zero); einige verwendeten inline flüssigkeitsgekühlte Motoren (Bf-109, Mustang, Yak-7, Spitfire); und einige verwendeten zwei Motoren anstelle von einem (P38, Do-335). Einige benutzten Maschinengewehre, einige benutzten Kanonen und einige benutzten beides. Einige waren sogar aus Sperrholz, wenn Sie es sich vorstellen können.
Am Ende waren sie alle sehr schnell und in den Händen eines kompetenten, erfahrenen Piloten, würden sie deinen Rookie-Arsch in einem Herzschlag abschießen. Ich kann mir nicht vorstellen, dass viele Piloten herumgeflogen sind und gedacht haben "Oh, dieser Idiot fliegt etwas mit einem Sternmotor - ich muss mir keine Sorgen um ihn machen". Jeder verstand, dass es viele verschiedene Möglichkeiten gab, das ultimative Ziel zu erreichen, und jeder Ansatz hatte seine besonderen Vor- und Nachteile, abhängig von den Umständen.Die Debatte zwischen ORM und herkömmlichem Datenzugriff ist genau so, und es obliegt jedem Programmierer, mit beiden Ansätzen kompetent zu werden und die für die jeweilige Aufgabe passende Option zu wählen.
Ich habe lange mit dieser Entscheidung gekämpft. Ich glaube, ich war aus zwei Gründen zögerlich. Erstens, O / R-Mappers waren ein Mangel an Kontrolle über das, was in einem kritischen Teil der App passierte, und zweitens, weil ich so oft von Lösungen enttäuscht wurde, die für den 90% Fall fantastisch sind, für den Letzten jedoch miserabel sind 10%. Alles funktioniert natürlich für ausgewählte Autoren, aber wenn Sie die Komplexität ankurbeln und ein hochvolumiges, kritisches System haben und Ihre Karriere auf dem Spiel steht, müssen Sie die vollständige Kontrolle über jedes Suchmuster und jedes Byte haben über den Draht. Die meisten Entwickler, einschließlich mir, sind frustriert, wenn das Tool uns zum ersten Mal ausfällt, und wir können nicht tun, was wir tun müssen, oder unser Bedarf weicht von dem etablierten Muster ab, das vom Tool unterstützt wird. Ich werde wahrscheinlich wegen der Erwähnung bestimmter Fehler in den Werkzeugen geflammt werden, also werde ich es dabei belassen.
Glücklicherweise hat mich Anderson Imes schließlich davon überzeugt, CodeSmith mit der netTiers-Vorlage . (Nein, ich arbeite nicht für sie.) Nachdem ich mehr als ein Jahr damit verbracht habe, kann ich nicht glauben, dass wir es nicht früher gemacht haben. Mein Team verwendet Visual Studio DB Pro und bei jedem weiteren Check-in wird bei der kontinuierlichen Integration ein neuer Satz von Datenzugriffslayer-Assemblys ausgeschlossen. Dies erledigt automatisch alle üblichen, wenig riskanten Dinge, aber wir können trotzdem benutzerdefinierte Sprocs für die kniffligen Bits schreiben und sie als Methoden in die generierten Klassen aufnehmen, und wir können auch die Vorlagen für den generierten Code anpassen. Ich empfehle diesen Ansatz sehr. Möglicherweise gibt es auch andere Tools, die diese Kontrolle ermöglichen, und es gibt eine neuere CodeSmith-Vorlage namens PLINQO, die LINQ to SQL unter der Haube verwendet. Wir haben das noch nicht untersucht (was nicht nötig war), aber dieser Gesamtansatz hat eine Menge Vorteile.
Jerry
O / RM-Tools, die in den meisten Situationen sehr gut funktionieren. Es speichert Entitäten für Sie, es führt Abfragen in Bulks aus, es hat einen sehr niedrigen Level optimierten Zugriff auf Objekte, was viel schneller ist als die manuelle Zuweisung von Werten zu Eigenschaften, sie geben Ihnen eine sehr einfache Möglichkeit, Variationen der aspektorientierten Programmierung zu integrieren Moderne Techniken wie Interzeptoren, es wird den Entity State für Sie verwalten und helfen, Konflikte und vieles mehr zu lösen.
Nun liegt dieser Ansatz in der Regel daran, dass man nicht versteht, wie die Dinge auf einem sehr niedrigen Niveau funktionieren. Das klassische Problem ist "SELECT N + 1" ( link ).
Ich arbeite jetzt seit 2,5 Jahren mit NHibernate und entdecke fast täglich etwas Neues darüber ...
Gut. In den meisten Fällen.
Der Produktivitätsvorteil bei der Verwendung eines ORM wird in den meisten Fällen den Verlust der Kontrolle darüber ausgleichen, wie auf die Daten zugegriffen wird.
Es gibt nicht so viele, die C # vermeiden würden, um MSIL oder Assembly zu programmieren, obwohl das ihnen mehr Kontrolle geben würde.
Das Problem, das ich bei vielen ODER-Mappern sehe, ist, dass Sie aufgeblähte Domänenobjekte erhalten, die normalerweise stark mit dem Rest Ihres Datenzugriffs-Frameworks gekoppelt sind. Auch unsere Entwickler sind davon betroffen :) Es ist nur schwieriger, diese Objekte auf eine andere Datenzugriffstechnologie zu portieren. Wenn Sie L2S verwenden, können Sie sich den generierten Code ansehen. Es sieht wie ein komplettes Durcheinander aus. NHibernate ist wahrscheinlich einer der besten. Ihre Entitäten sind sich Ihrer Datenzugriffsebene nicht bewusst, wenn Sie sie richtig gestalten.
Es hängt wirklich von der Situation ab.
Ich ging von einer Firma, die ein ausgezähltes ORM verwendet, zu einer Firma, die kein ORM benutzt und ständig SQL-Abfragen geschrieben hat. Als ich nach einem ORM gefragt habe, um den Code zu vereinfachen, bekam ich diesen leeren Ausdruck, gefolgt von allen Negativen:
an einem an
Nun, nachdem ich ein paar Wochen dort gearbeitet hatte, hatte ich folgendes bemerkt:
Nachdem ich das meiste darauf hingewiesen habe, haben sie eine "DBO" geschrieben, weil sie sie nicht als ORM bezeichnen wollte. Sie entschieden sich dafür, einen von Grund auf neu zu schreiben, anstatt ihn zu optimieren.
Auch viele Argumente kommen aus der Ignoranz gegen ORM, die ich fühle. Jedes ORM, das ich gesehen habe, erlaubt benutzerdefinierte Abfragen, und selbst nach den ORM-Konventionen können Sie sehr komplexe und detaillierte Abfragen schreiben und sind normalerweise menschlicher lesbar. Außerdem neigen sie dazu, sehr TROCKEN zu sein. Du gibst ihnen dein Schema, und sie stellen den Rest dar, bis hin zum Relationship Mapping.
Moderne ORMs haben viele Tools, die Ihnen helfen, wie Migrationsskripte, mehrere DB-Typen, die auf die gleichen Objekte zugreifen, so dass Sie die Vorteile von NOSQL- und SQL-DBs nutzen können. Aber Sie müssen das richtige ORM für Ihr Projekt auswählen, wenn Sie eines verwenden möchten.
Ich kam zuerst in ORM Mapping und Data Access Layers von Rockford Lhotka Buch, C # Business-Objekte. Er hat jahrelang an einem Framework für DALs gearbeitet. Während sein Framework out of the box ziemlich aufgebläht und in manchen Fällen übertrieben ist, hat er einige ausgezeichnete Ideen. Ich empfehle das Buch für jeden, der ORM Mapper betrachtet. Ich war von seinem Buch genug beeinflusst, um viele seiner Ideen wegzunehmen und sie in meine eigene Framework- und Code-Generation zu integrieren.
Es gibt keine einfache Antwort darauf, da jeder ORM-Anbieter seine eigenen besonderen Vor- und Nachteile hat. Einige ORM-Lösungen sind flexibler als andere. Es liegt in der Verantwortung des Entwicklers, diese zu verstehen, bevor er eine verwendet.
Nehmen Sie jedoch LinqToSql - wenn Sie sicher sind, dass Sie nicht von SQL Server wechseln müssen, dann löst dies viele der in ORM-Mappern häufig auftretenden Probleme. Sie können gespeicherte Prozeduren einfach hinzufügen (als statische Methoden), sodass Sie nicht nur auf generiertes SQL beschränkt sind. Es verwendet die verzögerte Ausführung, sodass Sie Abfragen effizient miteinander verketten können. Es verwendet partielle Klassen, mit denen Sie problemlos benutzerdefinierte Logik zu generierten Klassen hinzufügen können, ohne sich Gedanken darüber machen zu müssen, was passiert, wenn Sie sie neu generieren. Es gibt auch nichts, was Sie daran hindert, LINQ zu verwenden, um Ihre eigene abstrahierte DAL zu erstellen - es beschleunigt den Prozess nur. Die Hauptsache ist jedoch, dass es die Langeweile und die Zeit verringert, die zum Erstellen einer grundlegenden CRUD-Schicht erforderlich sind.
Aber es gibt auch Nachteile. Es wird eine enge Kopplung zwischen Ihren Tabellen und Klassen geben, es wird einen leichten Leistungsabfall geben, Sie können gelegentlich Abfragen generieren, die nicht so effizient sind, wie Sie es erwartet haben. Und Sie sind an SQL Server gebunden (obwohl einige andere ORM-Technologien datenbankunabhängig sind).
Wie gesagt, Hauptsache ist, sich der Vor- und Nachteile bewusst zu sein, bevor Sie Ihre Farben an eine bestimmte Methode anpassen.
Tags und Links orm data-access-layer