Was sind einige Argumente GEGEN die Verwendung von EntityFramework? [geschlossen]


31

Die Anwendung, die ich gerade erst erstelle, verwendet gespeicherte Prozeduren und handgefertigte Klassenmodelle, um Datenbankobjekte darzustellen. Einige Leute haben vorgeschlagen, Entity Framework zu verwenden, und ich denke darüber nach, dorthin zu wechseln, da ich noch nicht so weit im Projekt bin. Mein Problem ist, ich habe das Gefühl, dass die Leute, die für EF streiten, mir nur die gute Seite der Dinge erzählen, nicht die schlechte Seite :)

Meine Hauptanliegen sind:

  • Wir möchten eine clientseitige Validierung mithilfe von DataAnnotations, und es klingt, als müsste ich sowieso clientseitige Modelle erstellen, sodass ich nicht sicher bin, ob EF so viel Codierungszeit einsparen würde
  • Wir möchten die Klassen so klein wie möglich halten, wenn wir über das Netzwerk gehen, und ich habe gelesen, dass die Verwendung von EF häufig zusätzliche Daten enthält, die nicht benötigt werden
  • Wir haben eine komplexe Datenbankschicht, die mehrere Datenbanken umfasst, und ich bin nicht sicher, ob EF damit umgehen kann. Wir haben eine gemeinsame Datenbank mit Benutzern, Statuscodes, Typen usw. und mehreren Instanzen unserer Hauptdatenbanken für verschiedene Instanzen der Anwendung. SELECT-Abfragen können und werden über alle Instanzen der Datenbanken hinweg abgefragt. Benutzer können jedoch nur Objekte ändern, die sich in der Datenbank befinden, an der sie gerade arbeiten. Sie können die Datenbank wechseln, ohne die Anwendung neu zu laden.
  • Objektmodi sind sehr komplex und es sind oft einige Verknüpfungen beteiligt

Argumente für EF sind:

  • Parallelität. Ich müsste nicht vor jedem Speichern in Schecks codieren, um zu sehen, ob der Datensatz aktualisiert wurde
  • Codegenerierung. EF kann Teilklassenmodelle und POCOs für mich generieren. Ich bin jedoch nicht sicher, dass dies mir wirklich so viel Zeit ersparen würde, da ich denke, dass wir noch clientseitige Modelle für die Validierung und einige benutzerdefinierte Analysemethoden erstellen müssten.
  • Entwicklungsgeschwindigkeit, da die gespeicherten CRUD-Prozeduren nicht für jedes Datenbankobjekt erstellt werden müssten

Unsere aktuelle Architektur besteht aus einem WPF-Dienst, der Datenbankaufrufe über parametrisierte gespeicherte Prozeduren, POCO-Objekte, die zum / vom WCF-Dienst und dem WPF-Client gehen, und dem WPF-Desktop-Client selbst, der POCOs zum Zweck der Validierung und in Klassenmodelle umwandelt Datenbindung.

Also meine Frage ist, ist EF richtig dafür? Gibt es irgendwelche Fallstricke bei EF, von denen ich nichts weiß?


Schauen Sie sich auch dies an. Ein Vergleich von Leistung und LINQ-Unterstützung: ormeter.net
M.Sameer

Antworten:


7

Ich habe kürzlich Entity Framework evaluiert. Der beste Ort, an dem ich Probleme und fehlende Funktionen gefunden habe, war: http://data.uservoice.com/forums/72025-ado-net-entity-framework-ef-feature-suggestions

Die Artikel mit den meisten Stimmen:

  1. Unterstützung für Aufzählungen. Dieser ist ziemlich groß, aber es gibt derzeit einige Problemumgehungen
  2. Verbesserte SQL-Generierung. Geschwindigkeit ist wirklich wichtig, insbesondere für Anwendungen auf Unternehmensebene, aber es scheint, als hätte sich mit EF4 eine Menge verbessert
  3. Unterstützung für mehrere Datenbanken. Voraussetzung für jede große Anwendung.

Es gibt noch viele weitere Probleme in der User Voice-Liste.

Ich freue mich ziemlich auf die bevorstehende Veröffentlichung von EF 4.1, die den Code-First-Ansatz enthalten wird ... http://blogs.msdn.com/b/adonet/archive/2011/03/15/ef-4 -1-Release-Kandidat-verfügbar.aspx

Das könnte mich dazu bringen, EF in einer Produktionsanwendung zu testen.


Argument gegen: 1. & 2. & 3.: Es ist langsam !!! Es gibt eine Lernkurve (man muss wissen, wie man einen Link-Join macht - es dauert 3 Stunden, um herauszufinden, wie man es macht, damit eine andere Person weiß, was gerade gemacht wird ...), in LINQ anstatt in SQL zu pagen (z. B. Feches) 10 Millionen Zeilen, dann nehmen Sie 20 davon von einem beliebigen Versatz und fragen sich dann, warum es so langsam ist. Das Repo ist nicht laufflächensicher, Sie müssen es abfragebasiert initialisieren und die Repo-Initialisierung ist SEHR LANGSAM (wie 5 Sekunden), wenn Sie eine größere Datenbank haben (das bedeutet 100-200 Tabellen, nicht WIRKLICH WIRKLICH groß).
Quandary

2
@Quandary Scheint, als würden Sie IQueryables ausführen (z. B. aufrufen .ToList()oder .ToArray), bevor Ihre LINQ-Ausdrücke vollständig definiert sind. Deshalb zieht es alle Datensätze und macht es langsam.
Orad

6

Das Ausführen von Branch-per-Bug / Feature mit EF kann beim Zusammenführen sehr schmerzhaft sein. Stellen Sie sich vor, dass zwei Zweige A und B Änderungen an der Datenbank vornehmen (was wahrscheinlich in den frühen Phasen eines neuen Projekts häufig vorkommt).

Sie führen alle "normalen" Dateien zusammen - cs-Dateien usw. Und dann ist es Zeit, Model.edmx zusammenzuführen. Und plötzlich verbinden Sie nicht nur die logischen Zuordnungen zwischen Ihrem Objektmodell und der Datenbank, sondern auch die Positionen der Tabellen im Entitätsdiagramm.

Das Zusammenführen von Model.edmx ist so schmerzhaft, dass wir eine ziemlich böse Methode gewählt haben, die funktioniert:

  • Wählen Sie während der Zusammenführung einfach alle Zusammenführungen eines übergeordneten Elements aus. Welches spielt keine Rolle; Du wirst die Datei sowieso bald rösten:
  • Setzen Sie Model.edmx auf eines der übergeordneten Elemente zurück.
  • Migrieren Sie Ihre Datenbank in den neuen Status "Zusammengeführt".
  • Öffnen Sie die Datei Model.edmx und "Update Model from Database".
  • Benennen Sie alle Navigationseigenschaften um, die während der Zusammenführung geröstet wurden.

1
Diese Kritik gilt nicht für EF Code First, sondern für Model First und Database First.
Alan Macdonald

Ich erstelle alle Zuordnungen selbst mit Fluent und übernehme die volle Kontrolle über die Zuordnung. Diese befinden sich in einer separaten CS-Datei.
Steven Ryssaert

5

EF bietet Ihnen noch einige weitere Vorteile:

  • Sie können eine Entitätsspanne Tabellen haben
  • Sie können eine Tabelle in mehrere Entitätstypen aufteilen
  • Sie können die Entities aus der Datenbank generieren (dh Datenbank als Master-Ansatz)
  • Sie können die Datenbank aus Entities generieren (dh Code als Master-Ansatz)
  • LINQ-Abfragen werden in SQL-Abfragen übersetzt, wodurch ihre Leistung verbessert wird.

Die Nachteile (insbesondere, wenn Sie die Validierung verwenden):

  • Sie müssen ein Attribut [MetadataClass] erstellen, das auf eine andere Klasse mit den Eigenschaften verweist, die Sie mit den entsprechenden Validierungsattributen validieren möchten. Alle Eigenschaften sind objectTypen, sodass nur die Metadaten gelesen werden können. Immer noch viel zusätzlichen inaktiven Code.
  • Die Verwendung von EntityFramework unterscheidet sich von der Funktionsweise von NHibernate (und der übergeordneten Java-Version). EntityFramework funktioniert am besten in einem angehängten Modus, in dem die Objekte jederzeit eine Live-Verbindung verwenden. NHibernate und ähnliche ORM-Tools funktionieren am besten im getrennten Modus, wenn die Verbindung nur zum Laden / Speichern von Daten verwendet wird.

Das sind die beiden größten Beschwerden, die ich habe. Es gibt eine Reihe von Vorteilen, aber möglicherweise können Sie die gleichen Vorteile von NHibernate nutzen. Wenn EntityFramework auf dem Tisch liegt, lassen Sie das Team auch NHibernate überprüfen und schnell nach den Vor- und Nachteilen für Ihr Projekt suchen .

Das Metadatenklassenproblem bereitet mir Kopfschmerzen, aber zum Glück habe ich nur so viele Entitäten, die Validierungs-Tags benötigen.

Das Fehlen eines echten getrennten Modus für Ihre Objekte schränkt die Möglichkeiten in einer Webumgebung ein. Der angehängte Modus eignet sich besser für Desktopanwendungen, aus denen eine Reihe von Innovationen von Microsoft hervorgegangen sind. Freistehender Modus ist möglich , aber sehr schmerzhaft. Verwenden Sie in diesem Fall am besten ein alternatives Tool.


Ihr sogenannter Code als Master- Ansatz wird offiziell zuerst als Code bezeichnet
Robert Koritnik

1
@Berin, ich möchte klären, was du mit "angehängter Modus" meinst. Ich glaube nicht, dass Entity Framework jederzeit eine Verbindung zur Datenbank hat. Ich glaube, EF funktioniert in dieser Hinsicht ähnlich wie NHibernate. Ist es das was du meinst oder meinst du etwas anderes? Haben Sie einen Link zur Dokumentation, die dieses angehängte Problem näher erläutert?
RationalGeek

1
Mit angehängt meine ich, dass alle Ihre Interaktionen mit den Objekten innerhalb des using(EFConnection conn = new EFConnection)Konstrukts stattfinden müssen. Wenn Sie versuchen, dieses Objekt an einem sicheren Ort zu verwahren, damit Sie ein schnelles Update durchführen und es in einer zweiten using(...)Anweisung erneut speichern können, müssen Sie erneut darüber nachdenken. Siehe msdn.microsoft.com/en-us/library/bb896271.aspx und msdn.microsoft.com/en-us/library/bb896248.aspx . Die Verwendung von EF 3.5 (das ich in der letzten Version verwenden musste) ist nicht einmal so sauber.
Berin Loritsch

Okay, ich verstehe, was du jetzt meinst. Ich wollte nur sicherstellen, dass die Leute das nicht so verstehen, dass immer eine Verbindung zur Datenbank besteht . Sie müssen über einen Objektkontext verfügen, der den Status von "angehängten" Entitäten beibehält.
RationalGeek

2
Das ist nicht wahr. EF hat eine starke Vorstellung von getrennten Einheiten. Eine getrennte Entität muss erneut mit ihrem Kontext verbunden werden, bevor Sie kontextbezogene Vorgänge für sie ausführen können (z. B. das Aktualisieren in der Datenbank). Außerdem sind die Metadatenklassen nur erforderlich, wenn EF Ihre Entitäten für Sie generiert. POCOs, IMO, sind eine viel bessere Möglichkeit, die EF zu verwenden. Die Verwendung von POCOs vereinfacht vieles, insbesondere das Testen.
Matt Greer

2

Eine Sache, in der Microsoft nicht besonders gut ist, ist die Abwärtskompatibilität, insbesondere bei neuen Technologien

Insbesondere EF1 (.net 3.5) unterscheidet sich stark von EF4 (.net 4.0) - dies kann auch bei der nächsten Version der Fall sein.

Ich würde eine Weile warten und sehen, wie die Technologie reift.

In der Zwischenzeit sollten Sie nHibernate in Betracht ziehen - es ist nicht äquivalent, aber es ist ausgereift und wird häufig verwendet.


1
  • Ganz einfach: Das Domänenmodell ist selten eine Kopie des relationalen Modells in Ihrer Datenbank. Einige Tabellen einer Klasse zuzuordnen und sie über den Draht zu werfen, ist einfach nur Faulheit. Tabellen können lokal einem Objekt zugeordnet werden, obwohl die Datenbank aus 3 verschiedenen Tabellen besteht. Gestalten Sie die Datenbank intelligent.
  • 2. Dieses EF-Zeug kann bestimmte Abfragen nicht erzeugen und Sie müssen sie trotzdem schreiben.
  • 3. Das Domain-Modell wird nicht direkt auf Dienste abgebildet. Man möchte nur den geringsten Datensatz als DTOs über das Netzwerk übertragen. Insbesondere, wenn die Kommunikation mit mobilen Apps erfolgen soll.
  • 5. Testfähigkeit ... Kann nicht granular genug Tests erstellen, die genug Regression gegen Codeänderungen bieten ... alles zu leicht zu
    knacken ...

Ich könnte eine 10-seitige Diatribe schreiben. Aber wenn Sie nur eine Wurf-App für Unternehmen X schreiben, wen interessiert das dann? Aber wenn Sie ein Softwareprodukt entwickeln ... müssen Sie viel mehr anal sein


Dieser Beitrag ist ziemlich schwer zu lesen (Textwand). Hätten Sie etwas dagegen bearbeiten sie in eine bessere Form ing?
Mücke

EF generiert keine Domain-Objekte. Das sind DAO. Sie müssen die Daten aus dem Objekt verwenden, um Ihr Domänenobjekt zu erstellen. Sie sollten Domänenobjekte ohnehin nicht von einem Dienst zurücksenden. Erstellen Sie daher Ihr dünneres DTO aus Ihren Domänenobjekten, bevor Sie zurückkehren. EF sollte in der Lage sein, fast alles zu generieren, was Sie in LINQ ausdrücken können. Die Datenbank ist nicht Teil eines Komponententests, sondern Teil eines Funktionstests. Allerdings gibt es für EF In-Memory-Mocks. Andernfalls abstrahieren Sie Ihre EF-Abfragen in ein Repository und verspotten Sie dies stattdessen.
Sinaesthetic

Ja, da stimme ich zu. Ich beziehe mich vielmehr auf Muster, die von Martin Fowler und Carig Lairman aufgestellt wurden. Letztendlich kann ich CTEs, PARTITION BY oder CROSS APPLY nicht verwenden. Ich kann auch keinen IDataReader verwenden, mit dem der Overhead des Speichers niedrig gehalten werden kann. Auch wenn ich SQL Trace
starte

0

Überprüfen Sie dies: http://efvote.wufoo.com/forms/ado-net-entity-framework-vote-of-no-confidence/

Die wichtigsten Punkte sind:

  • Mangel an faulem Laden
  • Mangel an Beharrlichkeit Ignoranz
  • Das zum Speichern des Entitätsmodells verwendete Dateiformat enthält sowohl Visualisierungselemente als auch das Entitätsmodell selbst verursacht Zusammenführungsprobleme in der Teamumgebung.

Beachten Sie, dass der obige Link über EF1 spricht.

Auch dieser Link: http://ormeter.net/ zeigt, dass EF im Vergleich zu anderen ORMs in Bezug auf Leistung und LINQ-Unterstützung nicht das Beste ist.


Denken Sie daran, dass dies gepostet wurde, als EF 1 noch neu veröffentlicht wurde (oder möglicherweise noch in der Beta). Mit EF 4 ist die Situation heute weitaus besser, und viele der in diesem Misstrauensvotum angesprochenen Probleme wurden gelöst.
RationalGeek

Der letzte Punkt zählt immer noch und ist sehr wichtig.
M.Sameer

1
Die erste EF-Version war 3.5. Es wurden keine vier Hauptversionen von EF veröffentlicht.
Matt Greer

3
@Matt das ist richtig. Die aktuelle Version heißt jedoch EF 4, um sie an den Rest der .NET 4-Versionierung anzupassen.
RationalGeek

1
Ob es gültig ist oder nicht, sollte sich jedoch nicht auf die Zusammenfassung des Links auswirken. Stimmen werden zeigen, ob es gültig ist. :)
Adam Lear
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.