2013-08-20 11 views
7

Ich bin kürzlich zu Entity Framework 5 gewechselt. Nun möchte ich die POCO-Klassen aus einer bestehenden Datenbank generieren und außerdem brauche ich sowohl Lazy Loading als auch Change Tracking. Daher sollten alle skalaren Eigenschaften sowohl virtuelle als auch Navigationseigenschaften sein.So generieren Sie POCO-Proxies aus einer vorhandenen Datenbank

Das Hinzufügen eines neuen ADO.Net-Entitätsdatenmodells endet in einer EDMX-Datei und einigen anderen CS- und TTS-Dateien.

Erstens, ich frage mich, warum die generierten POCO-Klassen standardmäßig nicht die Anforderungen von Change Tracking Proxy erfüllen, d. H. Skalare Eigenschaften sind nicht virtuell.

Zweitens, wie kann ich Proxy-fähige Poco-Klassen generieren?

PS: Ich akzeptierte die Antwort der Slauma als die beste und einzige Antwort bisher, aber ich stimme dem ersten Teil nicht zu. Hier ist mein Argument

Slauma über zwei Probleme mit Proxy spricht: Einschränkungen und Leistung:

  • über die Beschränkungen für die Proxy-fähigen Einheiten: Wenn die Klassen sind in DB Ersten Methode von Entity erzeugt Framework, die Regeln, denen die Klassen folgen müssen, um Änderungs-Tracking-Proxys zu aktivieren, sind nicht so wichtig, da sie überhaupt nicht restriktiv sind. Wen kümmert es wirklich, ob die Navigationssammlungen IList oder HashSet sind? Über die Einschränkungen zu sprechen, ist nur dann sinnvoll, wenn in der Anwendung mindestens eine Klasse vorhanden ist und Tabellen daraus generiert werden sollen.

  • Komplexe Eigenschaften werden zuerst nicht in DB unterstützt. So können wir sie von unserer Diskussion ausschließen.

  • Über die Perfomance: In the addressed article und auch einige andere Experimente, die ich bisher studiert habe, sind die Ergebnisse nicht sehr überzeugend Proxy für Snapshot abzulehnen. Zuerst wurden die Experimente an einer großen Anzahl von Einheiten durchgeführt, und zwar 10.000. Es ist nicht unwahrscheinlich, dass ein Stapelprozess in Ihrer Anwendung (nicht in der Datenbank) mit einer großen Anzahl von Entitäten arbeitet, es werden jedoch bessere Ansätze wie die gespeicherte Prozedur angenommen. Zweitens, abhängig von der Art der Anwendung und den Bedürfnissen, beschäftigen wir uns in der Regel mit einer geringen Anzahl von Entitäten, zum Beispiel wenn das Repository-Muster implementiert und verwendet wird; Es gibt keinen Unterschied zwischen der Leistung von Proxy und Snapshot. Interessanterweise war in dem angesprochenen Experiment die erneute Zuweisung desselben Werts zu den Eigenschaften der einzige Fall, in dem die Proxy-Leistung dramatisch ausfällt. Aber wer macht das wirklich? Es ist sehr einfach, vorsichtig zu sein, um zu vermeiden, den Change Tracker wiederholt zu benachrichtigen. In diesem Fall tritt erneut ein erhebliches Problem auf, wenn eine große Anzahl von Zuständen behandelt wird.

Antwort

4

Erstens frage ich mich, warum die generierten POCO Klassen standardmäßig nicht die Anforderungen der Änderungsverfolgung Proxy erfüllen, das heißt skalare Eigenschaften nicht virtuell sind.

Die Verwendung von Änderungsverfolgungsproxys wird nicht als Standardänderungsstrategie empfohlen. Es wird genauer in this blog post erklärt. Im Wesentlichen ist der Hauptgrund für die Verwendung von Change-Tracking-Proxies - eine bessere Performance im Vergleich zu auf Snapshots basierenden Change-Tracking - nicht immer garantiert - und manchmal ist es sogar noch schlimmer - und die Liste der Nachteile ist länger als bei der Snapshot-basierten Änderungsverfolgung.

In der Vergangenheit waren die T4-Vorlagen, die POCO Einheiten erzeugt in der Tat alle Eigenschaften markiert - einschließlich skalaren Eigenschaften - wie virtual und bereitete die Einheiten für die Proxy-basierte Änderungsverfolgung. Aus den im Blog beschriebenen Gründen wurde dies für die neueren Vorlagen, einschließlich des DbContext-Generators für EF 5, geändert, wie in this comment unter dem oben verlinkten Blogpost erwähnt. Jetzt sind nur Navigationseigenschaften als virtual markiert, aber keine skalaren Eigenschaften, die das verzögerte Laden ermöglichen, aber nicht für Change-Tracking-Proxys ausreichen.

Zweitens, wie kann ich Proxy-fähige Poco Klassen generieren?

Ich bin nicht bekannt, dass verfügbar T4-Vorlage, die dies tun würde, aber es ist ganz einfach die Standardvorlage zu ändern, auch die skalare Eigenschaften als virtual markieren:

  • In Ihrem Projekt, das Sie sollte zwei Dateien mit einer .tt Erweiterung haben: YourModelContainer.tt und YourModelContainer.Context.tt. Öffnen Sie die Datei YourModelContainer.tt.

  • In dieser Datei wird ein Verfahren Property genannt finden:

    public string Property(EdmProperty edmProperty) 
    { 
        return string.Format(
         CultureInfo.InvariantCulture, 
         "{0} {1} {2} {{ {3}get; {4}set; }}", 
         Accessibility.ForProperty(edmProperty), 
         _typeMapper.GetTypeName(edmProperty.TypeUsage), 
         _code.Escape(edmProperty), 
         _code.SpaceAfter(Accessibility.ForGetter(edmProperty)), 
         _code.SpaceAfter(Accessibility.ForSetter(edmProperty))); 
    } 
    

    Wechsel mit der Linie ...

     Accessibility.ForProperty(edmProperty), 
    

    ... bis ...

     AccessibilityAndVirtual(Accessibility.ForProperty(edmProperty)), 
    

das ist es.

Nur um es zu erwähnen, falls Sie nicht damit vertraut sind, aber es gibt eine zweite Art von Datenbank-First-Ansatz zur Verfügung, das ist Reverse Engineering an existing database to a Code-First model. Dieser Ansatz verwendet keine T4-Vorlage, sondern erstellt ein Code-First-Modell und einen Kontext mit Fluent-API-Mapping. Es ist nützlich, wenn Sie die Modellklassen anzupassen und erweitern möchten, und gehen Sie mit Code-First-Workflow (und-Code-First-Migrationen) in Zukunft (auch virtual Modifikatoren dann manuell hinzufügen könnte), um Ihre Datenbank-Schema zu aktualisieren und zu entwickeln.

+0

Vielen Dank für Ihre Antwort. Ich stimme dem ersten Teil Ihrer Antwort nicht zu und ich habe meine Frage aktualisiert, um die Argumente widerzuspiegeln. Der zweite Teil war jedoch sehr nützlich. Ich kenne das Code-First-Modell, aber es geht mich nichts an. – Alireza

+0

@Alireza: Teilweise stimme ich mit Ihrem Kritiker des ersten Teils überein. Ich war selbst ein Fan von Proxies zur Änderungsverfolgung (http://stackoverflow.com/a/7112470/270591) und sie waren ein Lebensretter in einem meiner Projekte. Nach Arthur Vickers Artikel wurde ich vorsichtiger, sie zu benutzen. Der erste Teil war mehr oder weniger nur ein Zitat des Standpunkts des EF-Teams, um zu erklären, warum sie wahrscheinlich den "virtuellen" Modifikator aus den Skalareigenschaften entfernt haben, wenn die neueren t4-Templates die POCOs erzeugen. – Slauma

+1

Vielleicht haben sie argumentiert, wie du gesagt hast, aber trotzdem konnten sie lernen, Proxy wieder zu aktivieren. Dies wurde von Microsoft so leise gemacht, dass man meinen könnte, es gäbe einen Bug im Proxy. – Alireza