7 Stimmen

WCF, Entity Framework und Datenkontrakte

Mit VS 2008 und .NET 3.5 SP1:

Ich verwende WCF, um Clients die Verbindung zu einem Dienst zu ermöglichen, der Datenbankeinträge mit Entity Framework liest und schreibt. Standardmäßig wird auf die Entitäten, die automatisch aus der Datenbank generiert werden, das Attribut DataContract angewendet.

Leider sind viele der Felder ausgesetzt sind nicht für den Verbrauch durch den Client (d.h. - Datensätze, wer auf welche Daten zugreift, usw.) und aus Sicherheitsgründen würde ich lieber halten sie von ausgesetzt werden. Gibt es eine Möglichkeit zu vermeiden, dass Entity Framework-Klassen auf diese Weise offengelegt werden?

備考 : Dies ist kein Duplikat von Wie kann man verhindern, dass private Eigenschaften in .NET-Entitäten über Dienste als öffentlich angezeigt werden? . In dieser Frage möchte der Benutzer bestimmte Felder selektiv anzeigen, während ich möchte, dass die Entität überhaupt nicht als DataContract angezeigt wird.

Vielen Dank im Voraus.

13voto

John Saunders Punkte 159011

Ist Ihnen bewusst, dass Ihre Entitäten nicht eins zu eins mit der Datenbank übereinstimmen müssen? Sie können insbesondere Spalten oder sogar ganze Tabellen, die nicht relevant sind, weglassen.

Das Entitätsmodell ist als konzeptionelles Modell gedacht. Sie können leicht einen Satz von Entitäten für eine Gruppe von Clients (z. B. Webdienste) und einen anderen Satz erstellen, der auf dieselbe Datenbank abgebildet wird und für einen anderen Client (z. B. eine Webanwendung) gedacht ist.

Andererseits rate ich immer davon ab, Entity-Framework-Objekte über einen Webdienst zugänglich zu machen. Microsoft macht leider implementierungsabhängige Eigenschaften sichtbar, indem sie mit [DataMember] markiert werden. Ich habe dies soeben mit einem einfachen Dienst ausprobiert, der einen SalesOrderHeader von AdventureWorks zurückgibt. Mein Client erhielt Proxy-Versionen der folgenden EF-Typen:

  • EntityKeyMember
  • StructuralObject
  • EntityObject
  • EntityKey
  • EntityReference
  • RelatedEnd

Das sind keine Dinge, die Ihre Kunden wissen müssen.

Ich ziehe es vor, Datentransferobjekte freizulegen und die Eigenschaften von einem zum anderen zu kopieren. Offensichtlich ist dies besser durch Reflexion oder Code-Generierung, als von Hand. Ich habe es in der Vergangenheit mit Codegenerierung gemacht (T4-Vorlagen).

Eine Option, die ich noch nicht ausprobiert habe, ist AutoMapper .

3voto

Robert Punkte 2806

Wir verwenden separate Klassen für die DataContract-Objekte. Wir haben eine Schnittstelle mit einer Methode, ToContract(), und alle unsere Entitäten implementieren diese Schnittstelle in einer Teilklassendatei. Das ist zusätzliche Arbeit und eine Standardvorlage, aber es scheint der einfachste Weg zu sein, um die Trennung und Granularität der Kontrolle zu erreichen, die wir brauchen.

2voto

marc_s Punkte 701497

Ich sehe grundsätzlich zwei Möglichkeiten, die Sie tun können:

  1. Entweder Sie entfernen die Elemente, die Sie nicht freilegen möchten, aus dem DataContract, indem Sie das [DataMember]-Attribut für diese Elemente manuell entfernen; in diesem Fall wird WCF die Eigenschaften nicht serialisieren
  2. Sie definieren Ihre eigenen WCF DataContract-Klassen mit nur den von Ihnen gewünschten Mitgliedern und entwickeln eine Logik zur Konvertierung von Ihren EF-Entitäten in Ihren WCF DataContract, z. B. mit AutoMapper um die mühsamen Zuordnungsoperationen zwischen EF- und WCF-Entitäten zu eliminieren (oder zumindest einzuschränken).

Marc

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X