Entity Framework mit den Augen eines Außenstehenden

Hintergrund


Aber viele, viele schreiben über das Entity Framework. Tatsächlich ist dies das "Standard" -ORM für .NET und Microsoft Visual Studio ...

Vor nicht allzu langer Zeit habe ich ein ziemlich großes Projekt in die Hände bekommen. Als ich ankam, war das Projekt ungefähr drei Jahre alt. Technisch war es ein herzzerreißender Anblick. Eine grobe Messung ergab, dass die Webanwendung problemlos und völlig ungerechtfertigt etwa 1 GB Serverspeicher für einen gleichzeitigen Benutzer verbrauchte. Ich musste schnell und schnell herausfinden, was dort so interessant geschrieben war. Gute Lektion, wie es geht.

In diesem Projekt wurde das Entity Framework verwendet, um auf Daten in einer relationalen Datenbank zuzugreifen. Zusätzlich zu offensichtlichen Architektur- und Programmierdummheiten wie ToList () aus welchen Gründen auch immer, Include anything, Einschränkungen für Objektgruppen nicht auf Datenbankebene, sondern auf Anwendungsebene unter Verwendung von LINQ To Objects, traten Probleme nur im Zusammenhang mit Entity Framework auf.

Ich gestehe, ich kann mich nicht als aktive Benutzer und Experten des Entity Frameworks einstufen, weil Ich benutze seit vielen Jahren ein anderes ORM im praktischen Leben. Aber das ist gut so, denn ich kann Ihnen, liebe Leser, über die Merkwürdigkeiten des Entity Frameworks und verwandter Tools berichten, die das Auge eines externen Beobachters wahrnimmt. Ich kann nicht alles behandeln, aber ich sage Ihnen, was ich sehe, da ich genau dieses Entity Framework ausprobiert habe.

Sieben Mal messen oder Horror entwerfen


CodeFirst und DBFirst bieten keine. Und hier ist warum. Die Antwort hier ist sowohl philosophisch als auch praktisch.

CodeFirst. Natürlich bietet es die fortschrittlichsten Funktionen im Entity Framework und die volle Kontrolle. Einige sind bereit, vor Heiserkeit und vor einem Kampf für diesen Ansatz zu argumentieren. Mein Argument ist einfach: Solange Sie 5-10-15 Entitäten haben, können Sie die Struktur des Systems im Auge behalten. Gebrauch auf Gesundheit! Wenn die Rechnung an Hunderte geht, können Sie dies nicht mehr tun. Ich gehe sehr leicht zu Hunderten und so viel passt nicht in meinen Kopf. Auch in den Köpfen der Genossen, besonders wenn Sie eine neue Person in das Projekt einführen. Deshalb brauche ich Bilder. Kompakt, intuitiv und komfortabel. Darüber hinaus sollte das Modell nicht in einem Bild, sondern in mehreren, in Teilen, irgendwie objektiv ausgewählt werden. Außerdem sollte aus den Bildern irgendwie etwas generiert werden. Ich schreibe nicht hunderte Male den gleichen Typcode und mache trotzdem keine Fehler.

Vielleicht DBFirst? Nein, das ist auch nichts für mich. Wie mache ich Vererbung? Und dann, wie werde ich über die durch die Besonderheiten der Datenbank angewendeten denken? Dort und Ihre Datentypen. Wenn ich zum Beispiel VARBINARY geschrieben habe, muss ich in meinem Kopf daran denken, dass es sich hier um ein Bild handelt und irgendwo um etwas Haschisches. Nun, um dies separat zu dokumentieren oder um mit Freunden Folklore zu züchten. Multiplizieren Sie dies mit über 300 Einheiten. Nein, das ist unpraktisch. Nein, ich möchte in Anwendungsarten denken. Und was bleibt mir dann noch übrig?

Bleibt ModelFirst. Hier kann ich zumindest Entitäten in die Nähe dessen zeichnen, was ich später in C # erhalte, und .NET-Typen für Felder verwenden. Aber auch hier wird der Streurechen sorgfältig platziert:
  1. Designer Warum springen die Verbindungen schrecklich drauf? Und sie werden gemäß dem Diagramm ausgeführt, wie ich Visual Studio mag und nicht wie ich es mag, und in einigen Fällen sind sie verknotet? Ich möchte, dass sie an das Blatt genagelt werden und sich nicht ohne mein Wissen bewegen, sonst kann ich sie nach dem nächsten Öffnen des Diagramms nicht finden. Ich scheine zu verstehen, warum CodeFirst so beliebt ist.
  2. Wie einfach ist es, ein Modell in mehrere Diagramme zu schneiden? Nun, es ist unpraktisch für mich, 300 Objekte in einem Diagramm zu haben. Außerdem werde ich gefoltert, wenn ich die Maus in die Schieberegler stecke. Ja, und der Designer ist mit einer solchen Anzahl von Entitäten sehr langsam. Natürlich gibt es die Funktion „In neues Diagramm verschieben“, aber wie kann man dann, falls erforderlich, um die Diagramme zurück zu kombinieren, einen Teil der Entitäten verschieben und dieselben Entitäten in mehreren Diagrammen verwenden?
    Die Gurus sagen, es gibt einen Weg, es gibt einen. Es ist aus dem Bereich der manuellen Bearbeitung einer .diagram-Datei. Aber es ist notwendig, den Höchsten Plan zu kennen. Aber ich bin kein Guru, ich habe keine Zeit für Erleuchtung, ich muss angewandte Funktionalität rekrutieren.
  3. Hier habe ich zum Beispiel ein Feld vom Typ string gezeichnet. Es wird standardmäßig als nvarchar (max) in der Datenbank generiert. Wiegen Sie den Ingenieur, der diese Standardeinstellung hat, mit einem großzügigen Ruck. Nur für diesen Standard. Von Herzen In den Eigenschaften des Felds "EntitySet" können Sie den Typ nicht einmal für einen Fall ändern. Im Allgemeinen möchte ich diese Standardeinstellung jedoch so ändern, dass alle Zeichenfolgenfelder von einem anderen Datenbanktyp generiert werden. Was zu tun ist? In einem edmx-Texteditor für alle bearbeiten und dann nachfolgende Pannen beseitigen?
  4. Ich kann mit meinen Anwendungstypen immer noch nicht zeichnen. Die Auswahl an Typen ist im Designer begrenzt. Was soll ich tun, wenn ich während des Entwurfsprozesses auf meinen Anwendungstyp gekommen bin (oder bereits einen erstellt habe) und ORM nur erklären möchte, wie er in der Datenbank angezeigt wird und wie - im C # -Code? Nun, natürlich muss ich bei der Implementierung des Typs bestimmte Regeln beachten, zum Beispiel das Vorhandensein impliziter Konvertierungen in den nativen Typ oder die Implementierung des alten IConvertible in etwas.
  5. Was soll ich tun, wenn C # -Code, der Entitäten entspricht, etwas Besonderes enthalten soll? In diesem Fall wird vorgeschlagen, zu CodeFirst zurückzukehren. Oder willkommen in der mutigen neuen Welt von T4.
  6. Die festgelegte Vererbung im Editor ist nicht an einen "menschlichen" TPC gebunden (eine separate Tabelle für jede Klasse mit allen Feldern), sondern nur als:
    - TPT (eine separate Tabelle für jede Klasse nur mit ihren Feldern + Verbindung zum Vorfahren). Während der Auswahl haben Sie dann: JOINs für jede Vererbungsbeziehung - Probleme mit der Leistung und Kopfschmerzen beim Versuch, eine Einschränkung für anonymes SQL zu bilden;
    - TPH (alle Ebenen in eine Tabelle setzen, auf Normalisierung und andere reine Ideale spucken). Ich frage mich, wie Sie überhaupt an so etwas denken können.
    Wenn Sie weiterhin TPC möchten, lesen Sie erneut CodeFirst + ModelBinder. Ich nutze die Gelegenheit, um diesen Ingenieur zu begrüßen. Streuen Sie entsprechend der Anzahl der angewendeten Einheiten fette Sümpfe auf ihn.

Um zu verstehen, wie „bequem“ das Entwerfen ist, empfehle ich Ihnen, mit jemandem zu sprechen, der versucht, die Entity Framework-Entwurfstools beispielsweise für Oracle anzupassen. Vor allem Änderungen an einem vorhandenen Modell. Ich empfehle, eine Person des anderen Geschlechts für diesen Zweck zu finden. Der Kontrast der Weltbilder wird Ihre Diskussion schärfen.

Wo sind die Schlüssel zum Tank oder "unterhaltsame" Programmierung


Nun, mal sehen, wie das programmiert ist.
Beginnen wir mit einem einfachen: etwas erstellen und speichern:
CDLIBEntities dbctx = new CDLIBEntities();            
//Country ctr1 = dbctx.Country.Create();
Country ctr1 = new Country();
ctr1.primaryKey = Guid.NewGuid(); //Ах, да! Надо не забыть вручную сгенерировать первичный ключ.
ctr1.Name = "Greece";
//Publisher pblshr1 = dbctx.Publisher.Create();
Publisher pblshr1 = new Publisher();
pblshr1.primaryKey = Guid.NewGuid(); //Ах, да! Опять сгенерировать ключ...
pblshr1.Name = "First Publisher";
pblshr1.Country = ctr1.primaryKey; //Чёрт, я опять забыл, надо, надо помнить о ключах и везде расставлять вручную, иначе EF подумает, что нарушилась ссылочная целостность
pblshr1.Country1 = ctr1;
//dbctx.Publisher.Attach(pblshr1); //АУ! Почему я вообще должен здесь заботиться о том, какого типа у меня сущность??? Ведь итак понятно, какого она типа.
dbctx.Publisher.Add(pblshr1); // Ах, Attach не вправляет сущностям статус на создание, мне тоже нужно помнить, что новым объектам надо делать Add, а старым Attach, иначе всё сломается
                              // А может, статус сущности будет как-нибудь сам распознаваться?
dbctx.SaveChanges();


Es ist erstaunlich hier:
  1. Sie müssen die Primärschlüssel manuell initialisieren. Ist es nicht besser, ein separat vorgeschriebenes Muster zum Generieren des Primärschlüssels zu haben? Nun, und Management-Funktionen;
  2. Um Entitäten zu binden, müssen Sie nicht nur die Navigationseigenschaft, sondern auch den Fremdschlüssel korrekt festlegen, da das Entity Framework sonst die Verletzung der referenziellen Integrität schilt. Es ist nicht klar: Wenn jede Entität durch einen Schlüssel identifiziert wird, sollte ein Bündel durch ein öffentliches Feld automatisch eine relationale Beziehung bedeuten. Es ist so einfach, dass es nur ein öffentliches Feld bedeutet, aber es ist taub, komm schon, lieber Programmierer, denk daran, dass wir Primär- und Fremdschlüssel haben, also sitzen, als ob es nichts mehr zu tun gibt.
  3. Ja, es gibt einen Ansatz, bei dem Schlüssel für Objekte selbst in der Datenbank erstellt werden. Einerseits, warum nicht, besonders wenn der Schlüssel eine Ganzzahl ist, andererseits, bis ich die Speicheranforderung abgeschlossen habe, habe ich keine Möglichkeit zu verstehen, was der Schlüssel sein wird, und ihn weiter zu verwenden. Es macht besonders Spaß, mit dem konstruierten Objekt umzugehen, wenn es im Speicher und mit einem Schlüssel benötigt wird. Ob es jedoch in der Datenbank gespeichert werden muss, wird am Ende bestimmt.
  4. Das Anhängen oder Hinzufügen von Objekten zum Kontext erfolgt nur durch Aufrufen der Methode der Auflistung des entsprechenden Typs. Darüber hinaus werden verschiedene Methoden verwendet: Hinzufügen - Hinzufügen und Anhängen einer vorhandenen - Anhängen. Was ist so "praktisch"? Vielleicht ist die Frage, was, wo und wie man das Entity Framework zusammen mit .Net hinzufügt. Irgendwie wird es ohne mich verstehen, welcher Typ diese Entität ist und was damit passiert ist.
  5. Warum gibt es einen Kontext? Dem Programmierer verschiedene "interessante" Rätsel in den Kopf zu werfen? Zum Beispiel können Sie Instanzen einiger Stubs abschalten, aber nicht die wesentlichen Klassen selbst. Oder was passiert zum Beispiel, wenn Sie versuchen, Objekte aus verschiedenen Kontexten miteinander zu verbinden? Das wird wahrscheinlich Spaß machen. Wir müssen uns also daran erinnern, aus welchem ​​Kontext ich herausgekommen bin.

Es gibt viele Gesten für eine so einfache Aufgabe wie das Konstruieren und Verbinden von Entitäten miteinander.

Da wird das DBMS oder Under-Include gefragt


Mal sehen, was passiert, wenn das Entity Framework etwas aus der Datenbank liest. Das ist auch sehr interessant. Wie und wann es Abfragen erstellt und ausführt.

Schauen Sie sich edmx (ein Stück) an, um das Rätsel ein wenig vorzustellen:

Die Funktion, ein Modell in ein Bild zu exportieren, ist übrigens so implementiert, dass der Entwickler nicht nur viel Spaß und angenehme Minuten hat, sondern auch seine Freizeit aufhellt.
Wenn Sie ein relativ großes Modell exportieren, sieht die Auflösung des Bildes ungefähr so ​​aus:

Grundsätzlich gebe ich zu, dass es Menschen gibt, die dies erkennen können. Hier im Titel der Entität steht "BlueRay".

Und dann ist dir aufgefallen, dass ich die Kraft der Verbindungen "von Hand" auf dem Bild "kritzeln" musste, weil sind sie nicht sichtbar? Ich habe es absichtlich "schlimmer" gemacht. Denken Sie, dass die Exportprozedur einen Fehler enthält und die Leistung einfach nicht in das Diagramm gelangt ist? Nein, alles ist einfacher, es gibt keine Fehler, die Leistung wird ehrlich mit hellgrauen Symbolen auf weißem Hintergrund exportiert (schauen Sie sich die Enden der Links genau an). Dies wird wahrscheinlich durchgeführt, um die Farbauflösung von Monitoren zu überprüfen und die Farbwahrnehmungsentwickler zu schulen.

Wir möchten den Namen der CD, den Namen des Herausgebers und den Namen des Landes anzeigen. Es besteht die Versuchung, das Problem direkt zu lösen. Und was ist praktisch. Wir nehmen eine Sammlung aus dem Kontext, gehen die Zusammenhänge durch. Alle Daten werden irgendwie selbst aus der Datenbank gepumpt. Ja, man kann nicht darüber nachdenken, alles funktioniert, das Ziel ist erreicht, was sonst noch gebraucht wird.
Nachdem wir eine einfache Konstruktion implementiert haben, schauen wir uns an, welche Anforderungen EF in diesem Fall ausführt.
CDLIBEntities dbctx = new CDLIBEntities();
dbctx.Database.Log = (s => { textBox1.AppendText(string.Format("{0}{1}", s, Environment.NewLine)); }); //Так будем подглядывать, какие запросы выполняет EF
DVD[] dvds = dbctx.DVD.ToArray(); // Посмотрим, как много запросов будет в таком варианте
//DVD[] dvds = dbctx.DVD.Include("Publisher1").Include(@"Publisher1.Country1").ToList().ToArray(); //В таком варианте будет один запрос с joins, однако нужно ли читать ВСЕ поля из связанных таблиц? На практике это кошмар с ужасом
for (int i = 0; i < dvds.Length; i++ )
{ 
    textBox1.AppendText(string.Format("{0} {1} {2}", dvds[i].Name, dvds[i].Publisher1.Name, dvds[i].Publisher1.Country1.Name) );
    textBox1.AppendText(Environment.NewLine);
}
textBox1.AppendText("ОК" + Environment.NewLine);


Überprüfen Sie zunächst „auf der Stirn“ und führen Sie Folgendes aus: Look, das Entity Framework führt bis zu 5 Anforderungen aus, und jede Anforderung befindet sich auch innerhalb ihrer Verbindung.
Textbox-Ausgabe:
Verbindung eröffnet am 17.04.2015 11:01:19 +05: 00
SELECT 
    [Extent1]. [PrimaryKey] AS [primaryKey], 
    [Extent1]. [Version] AS [Version], 
    [Extent1]. [Capacity] AS [Capacity], 
    [Extent1]. [Name] AS [Name], 
    [Extent1]. [Publisher] AS [Publisher]
    FROM [dbo]. [DVD] AS [Extent1]
- Ausführung am 17.04.2015, 11:01:20 Uhr +05: 00 Uhr
- Abgeschlossen in 11 ms mit dem Ergebnis: SqlDataReader
Geschlossene Verbindung am 17.04.2015 11:01:20 +05: 00
Verbindung eröffnet am 17.04.2015 11:01:20 +05: 00
SELECT 
    [Extent1]. [PrimaryKey] AS [primaryKey], 
    [Extent1]. [Name] AS [Name], 
    [Umfang1]. [Land] AS [Land]
    FROM [dbo]. [Publisher] AS [Extent1]
    WHERE [Extent1]. [PrimaryKey] = @ EntityKeyValue1
- EntityKeyValue1: '5cba87e2-2809-4437-9ff3-5abfe0d21536' (Typ = Guid, IsNullable = false)
- Ausführung am 17.04.2015, 11:01:20 Uhr +05: 00 Uhr
- Abgeschlossen in 6 ms mit dem Ergebnis: SqlDataReader
Geschlossene Verbindung am 17.04.2015 11:01:20 +05: 00
Verbindung eröffnet am 17.04.2015 11:01:20 +05: 00
SELECT 
    [Extent1]. [PrimaryKey] AS [primaryKey], 
    [Extent1]. [Name] AS [Name]
    FROM [dbo]. [Country] AS [Extent1]
    WHERE [Extent1]. [PrimaryKey] = @ EntityKeyValue1
- EntityKeyValue1: '888c8fd2-1a12-4ec4-90fa-9742c29cae9e' (Typ = Guid, IsNullable = false)
- Ausführung am 17.04.2015, 11:01:21 Uhr +05: 00 Uhr
- Abgeschlossen in 2 ms mit dem Ergebnis: SqlDataReader
Geschlossene Verbindung am 17.04.2015 11:01:21 +05: 00
Film 3 Zweiter Verlag USA
Verbindung eröffnet am 17.04.2015 11:01:21 +05: 00
SELECT 
    [Extent1]. [PrimaryKey] AS [primaryKey], 
    [Extent1]. [Name] AS [Name], 
    [Umfang1]. [Land] AS [Land]
    FROM [dbo]. [Publisher] AS [Extent1]
    WHERE [Extent1]. [PrimaryKey] = @ EntityKeyValue1
- EntityKeyValue1: '65e0fb16-15aa-4591-8c8b-286e498d1203' (Typ = Guid, IsNullable = false)
- Ausführung am 17.04.2015, 11:01:21 Uhr +05: 00 Uhr
- Abgeschlossen in 0 ms mit dem Ergebnis: SqlDataReader
Geschlossene Verbindung am 17.04.2015 11:01:21 +05: 00
Verbindung eröffnet am 17.04.2015 11:01:21 +05: 00
SELECT 
    [Extent1]. [PrimaryKey] AS [primaryKey], 
    [Extent1]. [Name] AS [Name]
    FROM [dbo]. [Country] AS [Extent1]
    WHERE [Extent1]. [PrimaryKey] = @ EntityKeyValue1
- EntityKeyValue1: '658e951e-b56a-4423-b16a-b1dd2c7c293a' (Typ = Guid, IsNullable = false)
- Ausführung am 17.04.2015, 11:01:21 Uhr +05: 00 Uhr
- Abgeschlossen in 0 ms mit dem Ergebnis: SqlDataReader
Geschlossene Verbindung am 17.04.2015 11:01:21 +05: 00
Film 0 Erster Verlag Griechenland
Film 1 Zweiter Verlag USA
Film 4 Erster Verlag Griechenland
Film 2 Erster Verlag Griechenland
Ok


Dies liegt daran, dass EF nach dem Prinzip "Gib zurück, was du nimmst" arbeitet und sich dabei auf die Navigationseigenschaften bezieht. Für diese einfache Entwicklung gibt es eine harte Amortisation: In großen und komplexen Systemen ist dies nicht möglich, weil Dies führt zu einer Verschwendung von Ressourcen sowohl des DBMS als auch der Anwendung.

Es ist gut, dass EF eine Art Boot-Management-Tool hat. Kommentar hinzufügen. Lobe die Weisheit von EF! Jetzt JOIN für jede Navigation und nur eine Anfrage.
Textbox-Ausgabe:
  Geöffnete Verbindung am 17.04.2015 11:03:44 +05: 00
SELECT 
    1 AS [C1], 
    [Extent1]. [PrimaryKey] AS [primaryKey], 
    [Extent1]. [Version] AS [Version], 
    [Extent1]. [Capacity] AS [Capacity], 
    [Extent1]. [Name] AS [Name], 
    [Extent1]. [Publisher] AS [Publisher], 
    [Extent2]. [PrimaryKey] AS [primaryKey1], 
    [Extent2]. [Name] AS [Name1], 
    [Umfang2]. [Land] AS [Land], 
    [Extent3]. [PrimaryKey] AS [primaryKey2], 
    [Extent3]. [Name] AS [Name2]
    FROM [dbo]. [DVD] AS [Extent1]
    INNER JOIN [dbo]. [Publisher] AS [Extent2] ON [Extent1]. [Publisher] = [Extent2]. [PrimaryKey]
    INNER JOIN [dbo]. [Country] AS [Extent3] ON [Extent2]. [Country] = [Extent3]. [PrimaryKey]
- Ausführung am 17.04.2015, 11:03:45 Uhr +05: 00 Uhr
- Abgeschlossen in 16 ms mit dem Ergebnis: SqlDataReader
Geschlossene Verbindung am 17.04.2015 11:03:45 +05: 00
Film 0 Erster Verlag Griechenland
Film 4 Erster Verlag Griechenland
Film 2 Erster Verlag Griechenland
Film 1 Zweiter Verlag USA
Ok


Alles oder nichts


ABER das ist das Problem: Wenn wir nur Include schreiben, werden ALLE Eigenschaften unserer und verwandter Entitäten gelesen. Dies scheint der Schlüssel zu sein, um zu verstehen, wohin Gedächtnis und Geschwindigkeit gehen. "Re-include" sozusagen. Das Aufrufen von Include auf der Stirn ist schrecklich, insbesondere das Verzweigen für viele Navigationsaufgaben.

Versuchen wir es besser zu machen. Lösung: Wählen Sie nur die erforderlichen Felder aus den Entitäten aus und lesen Sie sie nur. Eine solche Menge kann als Projektion oder Repräsentation bezeichnet werden, für die sie bequem und bequem ist. Es ist gut, dass das Entity Framework eine solche Chance hat, jedoch eine Kurve.
Projektionslesung:
CDLIBEntities dbctx = new CDLIBEntities();            
dbctx.Database.Log = (s => { textBox1.AppendText(s); });
// 1. Связка анонимных типов (связка потому, что придётся для навигационных свойств тоже сделать анонимные типы)
var anon = dbctx.DVD.Select(x => new { primaryKey = x.primaryKey, Name = x.Name, Publisher1 = new {primaryKey = x.Publisher1.primaryKey, Name = x.Publisher1.Name } }).ToArray();
// 2. Объявленные типы (аналогично анонимному, только типы явно объявим, пример опустим, он очевиден)
// 3. Взять и сделать наследников от нужных сущностей (хотя бы явно типы писать не надо)
DVD_D[] dvd_derived = dbctx.DVD.Select(x => new DVD_D { primaryKey = x.primaryKey, Name = x.Name, Publisher1 = new Publisher_D { primaryKey = x.Publisher1.primaryKey, Name = x.Publisher1.Name } }).ToArray();


Es gibt 3 Möglichkeiten:
  1. Wir deklarieren einen anonymen Typ und wählen darin nur das aus, was benötigt wird;
  2. Wir schreiben eine spezielle Klasse nur mit den notwendigen Eigenschaften und verwenden sie;
  3. Wir stellen Erben aus den notwendigen Einheiten zusammen und füllen sie mit der Auswahl aus.

Was ist hier unbequem: Werden wir wirklich für jedes Sample schreiben? Ist es produktiv?

Und dann: Unser Ziel ist es nicht zu lesen, sondern weiterhin mit Entitäten zu arbeiten, d. H. Schreiblogik, die infolgedessen zu einer Änderung der Werte von Entitätsfeldern führt. Dies muss einfach zu bewerkstelligen sein: Ändern Sie den Wert der Eigenschaft der Entität und rufen Sie dann den Kontext auf, um ihn bei Bedarf zu speichern:
// Реально, очень хочется написать что-то навроде
dvd_derived[0].Name = "Зелёная сосиска";
dbctx.SaveChanges();

Da war es: Dieses Objekt wurde nicht aus dem Kontext erstellt und sein Typ ist EF unbekannt. Und wie speichern wir die Änderungen jetzt?

Die Krümmung ist, dass es völlig unverständlich ist, wie man die Änderungen speichert, ohne das Objekt mit allen Feldern VOLLSTÄNDIG aus dem Kontext zu nehmen.

Was zu tun Menschen erfinden! Zum Beispiel schreiben sie Klassen für jeden Projektionsfall und ordnen sie dann irgendwie den wesentlichen Klassen zu (die vom Kontext verstanden werden) und umgekehrt. Sie können auch separate Sätze von Entitätsklassen mit Sätzen von Eigenschaften haben, die Auswahlen entsprechen und auf dieselben Tabellen abgestimmt sind. Sie können, Sie können irgendwie ausweichen. Es muss eine aufregende Erfahrung sein. Das Wesentliche dieser Lektion passt jedoch nicht zur richtigen Philosophie, die darin besteht, dass ORM ORM ist und dass Konstruktionen in einer Programmiersprache eindeutig eine Objektessenz (OBJECTS) darstellen. Nicht dieser Teil ist da, der Teil ist hier. Hier lesen wir, hier ist es, hier kartieren wir, hier schneiden wir es, hier kleben wir es, hier wickeln wir den Fisch ein. Wenn ich eine Entität in den Code aufgenommen hätte, wäre ich überzeugt, dass alles, was ich brauche, hier ist und es nichts anderes im Code gibt, das für dieselbe Entität verantwortlich ist. Teilen und erobern, es gibt nichts, was die Funktionalität beeinträchtigen könnte. Ansonsten ist es kein ORM, sondern ein klassischer Krückensatz.

Anstelle einer Schlussfolgerung


Der Zweck der Verwendung von ORM besteht darin, den Programmierer auf die Lösung objektiver Probleme zu konzentrieren, ohne die Produktivität sowohl des Programmierers als auch der von ihm entwickelten Software zu beeinträchtigen. Die Arbeitsproduktivität sollte im Allgemeinen steigen. Es ist das 21. Jahrhundert, und die Frage des Zugriffs auf Daten wurde noch nicht geklärt. In dieser Form ist alles schön für das Schulhandwerk von 10 bis 20 Personen und passt mit Sicherheit nicht zu einer ernsthaften Aufgabe.

Kurz gesagt, ich verstehe nicht. Nun, für mich ist das Entity Framework eine Kuriosität aus geerbten Projekten, wir verwenden selbst ein anderes Produkt, das überhaupt nicht massiv und nicht populär ist, aber wie lebt die Mehrheit? In der Tat arbeiten und genießen Menschen auf der ganzen Welt das Leben, schreiben und geben Produkte aus? Nun, im Allgemeinen schlafen sie nachts friedlich. Immerhin habe ich es einfach genommen, aber richtig alles bröckelt in meinen Händen. Entweder sind ernsthafte, große Projekte auf etwas anderem geschrieben (ich frage mich worüber), oder alles ist dort manuell geschrieben, was im Allgemeinen schwer zu glauben ist. Leute, wie du lebst, verstehe ich nicht ...

Ich habe noch einen Trailer für Fragen zum Reservat. Aber es ist wahrscheinlich besser, wenn ich Ihnen im nächsten Artikel erkläre, welches ORM für mich als „Best Practices“ geeignet erscheint, wie es derzeit in Mode ist, es zu sagen. Huh?

Jetzt auch beliebt: