it-swarm.com.de

Sollte ich das Entity Framework für CRUD verwenden und die Datenbank die Komplexität von High-End-Abfragen bewältigen lassen?

Ich bin neu in ef und mag es, da es den Aufwand für das Schreiben allgemeiner Abfragen verringert, indem es durch einfache Funktionen zum Hinzufügen und Entfernen ersetzt wird. Einverstanden.

Heute habe ich mich mit meinem Kollegen gestritten, der es schon eine Weile benutzt, und mich an ihn gewandt, um Ratschläge zu erhalten, wann gespeicherte Prozeduren und wann EF verwendet werden sollen und wofür?

Er antwortete;

Schauen Sie, die einfache Sache ist, dass Sie beide verwenden können, aber was bringt es, ein ORM zu verwenden, wenn Sie alles in einer Datenbank ausführen, d. H. In gespeicherten Prozeduren. Wie würden Sie herausfinden, was wo und warum zu tun ist? Eine einfache Formel, die ich gelernt habe und die ORM für alle CRUD-Operationen und Abfragen verwendet, die 3-4 Verknüpfungen erfordern, aber darüber hinaus verwenden Sie besser gespeicherte Prozeduren.

Ich dachte, analysierte und antwortete;

Nun, das ist nicht der Fall, ich habe Blogs und Beispiele gesehen, in denen Leute massive Dinge mit EF machen und keine Prozedur schreiben mussten.

Aber er ist hartnäckig und nennt es Performance-Overhead, was ich noch nicht verstehen kann, da ich im Vergleich zu ihm relativ neu bin.

Meine Frage ist also, ob Sie CRUD nur in ef behandeln müssen oder in EF viel mehr tun sollten, um gespeicherte Prozeduren zu ersetzen.

4
azure boy

Ich neige dazu, Ihren Ansatz in dieser Angelegenheit zu verfolgen. ORMs eignen sich hervorragend für grundlegende CRUD- und relativ einfache Abfragen, aber oft ziehe ich es vor, direkt in die Datenbank zu gehen, normalerweise aus Leistungsgründen.

Ich kann in SQL Server eine komplexe Ansicht (oder einen Sproc) schreiben, die viel einfacher optimiert werden kann als dieselbe in Linq. Andererseits denke ich, dass es richtig ist, auch vorsichtig zu sein, wenn Sie die tatsächliche Logik in Ihre Datenbank einfügen.

ORMs sind ein Werkzeug für die Interaktion mit einer Datenbank, und für alltägliche Dinge können sie sich enorm vereinfachen, anstatt SQL-Anweisungen zu schreiben. Aber wie bei fast jedem anderen Tool ist es kein Wundermittel, die DB-Interaktion vollständig zu ersetzen.

Ich neige dazu, zwei Regeln zu haben, denen ich hier folge:

  1. Versuchen Sie, direkte DB-Objekte nur aus Gründen der Leistungsoptimierung zu verwenden, NICHT zur Berechnung der Geschäftslogik (manchmal die beiden sich kreuzenden Pfade, aber häufig können Sie Basisansichten/Sprocs als Quelle für eine .NET-Methode generieren, die dann den eigentlichen logischen Satz ausführt Vergleiche) und ...
  2. Verwenden Sie Ihre DBContext-Klasse/Repository-Klasse, um die Ansichten/Sprocs aufzurufen, die Sie möglicherweise für diese Optimierungszwecke erstellt haben. Das heißt, wenn Sie eine DBContext-Klasse haben, um Ihre Standard-EF-DBSets abzurufen, sollten Sie Ihre Aufrufe auch für die dortigen "unterstützenden Objekte" verfügbar machen und konsumieren (so könnte beispielsweise sproc dbo.GenerateReportSet Wie _context.GenerateReportSet(dateStart, dateEnd)
2
jleach

Aber er ist hartnäckig und nennt es Performance Overhead, was ich noch nicht verstehen kann

Es ist schwierig, eine detaillierte Diskussion über etwas zu führen, wenn Sie einen Teil des Problems nicht verstehen (und daher nicht anerkennen können).

Ganz einfach gesagt: Automatisierung kann nur so clever sein. Bei komplexen und komplizierten Abfragen generiert EF eine funktionierende Abfrage, die jedoch nicht so effizient ist, wie Sie es möchten.
EF ist nicht schlecht entwickelt. Die generierten ineffizienten Abfragen sind nur eine unvermeidliche Folge dessen, wofür EF entwickelt wurde (und was nicht). EF ist ein großartiges Tool, das trivialen und sich wiederholenden Code vermeidet. Diese Vorteile gehen jedoch verloren, wenn Sie hochgradig angepasste (im Allgemeinen komplexe) Abfragen bearbeiten.

Stellen Sie sich das so vor: Meine Limousine ist für den Straßenverkehr gebaut. Auf der Straße ist es viel einfacher zu fahren als mit einem großen Geländewagen. Kann ich mein Auto im Gelände fahren? Im Rahmen der Vernunft ja. Aber mein Auto wurde nicht für den Offroad-Einsatz gebaut, und daher gehen die Vorteile meines Autos verloren, wenn ich nicht unterwegs bin, während der 4x4 zu glänzen beginnt und leichter im Gelände zu fahren ist.
Wie mein Auto für den Straßenverkehr gebaut ist, ist EF für einfache CRUD-Aufgaben gebaut. Es kann auf andere Weise verwendet werden, aber niemand hat es in diesem Sinne entworfen.

"Schauen Sie, das Einfache ist, dass Sie beide verwenden können, aber was bringt es, ein ORM zu verwenden, wenn Sie alles in einer Datenbank ausführen, d. H. In gespeicherten Prozeduren."

Dieses Argument macht wenig Sinn. Was bringt es, eine Zahnbürste zu verwenden, wenn Ihr Arm die Zahnbürste trotzdem bewegt? Verwenden Sie einfach Ihren Arm, um Ihre Zähne zu reinigen!

Nun, das ist nicht der Fall, ich habe Blogs und Beispiele gesehen, in denen Leute massive Dinge mit EF machen und keine Prozedur schreiben mussten.

Nur weil es möglich ist, heißt das nicht, dass es gut gemacht wird. Ich habe Leute gesehen, die das Essen gegessen haben, aber das bedeutet nicht, dass ich ein guter Koch bin. Es bedeutet nur, dass ich nicht völlig unfähig bin zu kochen.

EF kann viele Dinge tun, aber seine Effizienz fällt mit zunehmender Komplexität der Abfrage auseinander. In Fällen, in denen der nachfolgende Leistungseinbruch nicht akzeptabel ist, ist EF nicht das zu verwendende Werkzeug.

Meine Frage ist also, ob Sie CRUD nur in ef behandeln müssen oder in EF viel mehr tun sollten, um gespeicherte Prozeduren zu ersetzen.

Wie bei vielen Dingen kommt es darauf an, was Sie brauchen.

Für einfache CRUD-Operationen ist EF ein gutes Werkzeug. Es entfällt die Notwendigkeit einer großen kesselbeschichteten Handhabungslogik.

Wenn Sie nur einfache Datenabfragen haben oder die Leistung nicht optimieren möchten, können Sie EF für diese verwenden, da Sie ohnehin bereits EF für CRUD verwenden.

Wenn Sie jedoch komplizierte Datenabfragen haben und sich um die Leistungsoptimierung kümmern, möchten Sie EF nicht verwenden. Unser leitender Architekt (der früher ein DBA war und sich sehr um die DB-Leistung kümmert) befürwortet derzeit die gleichzeitige Verwendung von EF und Dapper, insbesondere weil sie sich jeweils auf einen Teil der Arbeitslast spezialisiert haben. Anfangs schlug er vor, nur Dapper zu verwenden, aber er hat die Leichtigkeit von CRUD mit EF eingeräumt und akzeptiert dessen Verwendung in CRUD-lastigen Anwendungen.

Aber auch dies ist subjektiv. Möglicherweise möchten Sie sich lieber an ein Tool halten und die Nachteile beseitigen (z. B. EF verwenden und langsame komplexe Abfragen bearbeiten; oder Dapper verwenden und CRUD-Code für Boilerplates schreiben müssen). Oder Sie bevorzugen die Verwendung verschiedener Tools, damit Sie die Leistung jederzeit beeinträchtigen können.

2
Flater

Wie immer kommt es darauf an. Gespeicherte Prozeduren, Ansichten, Indizes und Trigger (usw.) sind hervorragende Werkzeuge für einen DBA. Sie stellen sicher, dass die (relationale) Datenbank selbst die Konsistenz garantiert, die richtigen Berechtigungen sicherstellt und so gut wie möglich funktioniert.

Diese Tools sind jedoch ein sicherer Weg zu einem datenbankzentrierten Design, bei dem sich das gesamte System um die Datenbank dreht. Dies bedeutet, dass sich der gesamte Code an das physische Datenbankmodell anpassen muss. Die von der Datenbank verwendeten Datentypen bestimmen speicherinterne Typen usw. Der Grund dafür ist, dass es sehr schwierig ist, ein Refactoring der Datenbankschicht aus Ihrem Geschäftslogikcode zu initiieren, wenn ein Recactoring das Umschreiben (und Testen/Debuggen) umfasst. gespeicherte Prozeduren, Trigger und benutzerdefinierter SQL-Code.

Der Hauptvorteil von EF (und ähnlichen Tools) besteht nicht (IMHO) darin, dass einfache CRUD-Komponenten einfach zu entwickeln sind, sondern dass das anschließende Refactoring dieser Komponenten viel einfacher wird. (Vorausgesetzt, Sie machen zuerst Code)

Ja, es ist ein Leistungspreis zu zahlen, sobald Sie mit komplexen Joins beginnen. Dieser Preis ist viel höher, wenn Sie einen naiven Ansatz für EF haben.

Jedoch

Wenn Sie aufgrund von SQL-Abfragen, die möglicherweise komplexe Verknüpfungen enthalten, auf echte Leistungsprobleme stoßen (da der Endbenutzer tatsächlich darunter leidet), sind gespeicherte Prozeduren bestenfalls eine Band-Hilfe.

Sie können den Speicher für die Datenintegrität oder die Abfrageleistung optimieren, jedoch nicht für beide. Wenn Sie beides benötigen, schauen Sie sich CQRS oder ähnliche Muster an.

TL; DR

  • EF beschleunigt das Schreiben und Umgestalten von Datenzugriffscode, was gut ist.
  • Der Preis hierfür sind nicht optimale Abfragen (schlimmer, wenn Sie keine Erfahrung mit EF haben).
  • Gespeicherte Prozeduren und andere DBA-Techniken können die DB-Leistung verbessern, was gut ist.
  • Der Preis dafür ist, dass Business Code schwieriger zu schreiben und umzugestalten ist.
  • Wenn die Abfrageleistung ein Problem darstellt (bei kompetenter EF-Verwendung), bewerten Sie das Gesamtdesign neu, anstatt zu versuchen, SQL zu optimieren.
2
Guran

Um noch zu dem hinzuzufügen, was @Guran geantwortet hat: Ich habe keine spezielle Erfahrung mit EF, aber ich habe gesehen, dass es leicht zu vergessen ist, dass Sie mit Joins und teuren Vorgängen zu tun haben, wenn Sie ein ORM verwenden. Sie beginnen also, Modellinstanzen als reguläre Variablen zu behandeln und sie in komplexe Operationen einzubeziehen, die wiederum wahrscheinlich zu noch komplexeren SQL-Abfragen werden. Ich habe auch clientseitigen Code mit Schleifen und Aggregationen gesehen, die auf dem Datenbankserver effizienter hätten ausgeführt werden können.

Wenn Sie also SQL/Stores-Prozeduren von Hand schreiben, sind Sie sich der Auswirkungen auf die Leistung bewusster.

1
sul4bh

In den meisten Fällen, in denen für einige Anforderungen ein Sproc benötigt wird. Platzieren Sie eine SQL-Skriptdatei in der Codebasis, die bei zukünftigen Refactoring-Anforderungen für Geschäftsregeln ausgeführt werden soll. Ich würde annehmen, dass die meisten neuen und erfahrenen Entwickler Erfahrung mit der Arbeit in einer Datenbank haben. Jeder, der die DB-Sproc-Anforderungen kennen muss, kann die Skripte nach Bedarf überprüfen und aktualisieren. Geschäftsregeln und DB-Anforderungen sind in den Quellcodedateien vorhanden. Ich glaube, dass es in den komplexesten Lösungen keine Einwegmethode gibt. (JMO).

0
Glh