2009-07-13 8 views
7

Korzystanie VS 2008 & .NET 3.5 SP1:WCF, Entity Framework i danych Kontrakty

używam WCF, aby umożliwić klientom połączyć się z usługą, która odczytuje i zapisuje dane bazy danych za pomocą Entity Framework. Domyślnie jednostki generowane automatycznie z bazy danych mają zastosowany atrybut DataContract.

Niestety, wiele z tych pól nie jest przeznaczonych do konsumpcji przez klienta (tj. - zapisy osób, które uzyskują dostęp do danych itp.), A ze względów bezpieczeństwa wolałbym, aby nie były narażone. Czy istnieje sposób na uniknięcie narażenia klas Entity Framework w ten sposób?

Uwaga: To nie jest duplikatem How to prevent private properties in .NET entities from being exposed as public via services?. W tym pytaniu użytkownik chce selektywnie wyświetlać określone pola, podczas gdy chciałbym, aby jednostka nie była w ogóle ujawniana jako DataContract.

Z góry dziękuję.

+0

To może być podobny do innego delegowania, który nie został całkowicie odpowiedział: „WCF i ADO Entity Framework”, http://stackoverflow.com/questions/828302/wcf-and-ado-entity-framework – Malcolm

+0

zgadzam się z odpowiedz na podany przez ciebie "framework encji wcf i ADO". Lub możesz zaimplementować jakiś schemat repozytorium. – NikolaiDante

+1

@Nath - Zdecydowanie zgadzam się z odpowiedzią na temat "struktury encji wcf i ADO", ale niestety to nie rozwiązuje mojego problemu. Pierwszym punktem odpowiedzi jest "Automatycznie generuj encje szkieletowe encji", które ujawnią dane, które chcę zachować jako prywatne jako Kontakty danych. Wzorzec repozytorium miałby ten sam problem, gdyby był również wspierany przez wygenerowany w ten sposób model EF - chyba że czegoś brakuje. – Malcolm

Odpowiedz

13

Czy zdajesz sobie sprawę, że podmioty nie muszą map jeden do jednego z bazy danych? W szczególności można pominąć kolumny, a nawet całe tabele, które nie są istotne.

Model encji ma być modelem koncepcyjnym. Można łatwo utworzyć zestaw encji dla ekspozycji na jeden zestaw klientów (może być to usługa sieciowa) i inny zestaw, mapując do tej samej bazy danych, która jest przeznaczona dla innego klienta (może to być aplikacja internetowa).

Z drugiej strony, zawsze zalecam, aby nigdy nie ujawniać obiektów Entity Framework za pośrednictwem usługi sieciowej. Microsoft niestety ujawnia właściwości zależne od implementacji, zaznaczając je za pomocą [DataMember]. Właśnie próbowałem tego z prostą usługą zwracającą SalesOrderHeader z AdventureWorks.My otrzymaliśmy klienckie wersje proxy następujących typów EF:

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

To nie są rzeczy twoich klientów o czym trzeba wiedzieć.

Preferuję ekspozycję obiektów przenoszenia danych i kopiowanie właściwości z jednej na drugą. Oczywiście lepiej robić to poprzez odbicie lub generowanie kodu niż ręcznie. Zrobiłem to poprzez generowanie kodu w przeszłości (szablony T4).

Opcja, której nie wypróbowałem to AutoMapper.

+0

Dziękuję za odpowiedź, John. Tak, zdaję sobie sprawę, że podmioty nie muszą mapować jeden do jednego i mogą modelować podzestaw modelu koncepcyjnego, ale nie sądzę, że da to wynik, na który mam nadzieję. Oto przykład: Załóżmy, że mam tabelę kont w systemie księgowym i chcę sprawdzić, jakie operacje są wykonywane na których rachunkach. Muszę ujawnić pola z tabeli kont, ale nie chcę, aby mój potencjalny oszust mógł zobaczyć, jakie informacje śledzę na temat jego działań. Ciąg dalszy w następnym komentarzu ... – Malcolm

+0

... Kontynuacja poprzedniego komentarza. Kiedy klient wywołuje funkcję, chcę utworzyć rekord i wstawić go do mojej tabeli kontroli w celu śledzenia i analizy. Chciałbym mieć oba dostępne za pośrednictwem EF (bez względu na to, czy są one w tym samym, czy osobnym kontenerze, nie są dla mnie ważne). Niestety to, co zdefiniowałem jako część modelu danych, zostanie ujawnione jako DataContract. – Malcolm

+0

Nie wystawiaj tego modelu danych. Odsłoń mniejszy model danych - ten, który chcesz eksponować. Nie wystawiaj tego samego modelu potencjalnemu oszustowi, tak jak robisz to w systemie audytu. –

3

Używamy oddzielnych klas dla obiektów DataContract. Mamy interfejs z jedną metodą ToContract(), a wszystkie nasze jednostki implementują ten interfejs w częściowym pliku klasy. To dodatkowa praca i jest to podstawa, ale wydaje się najprostszym sposobem na uzyskanie separacji i ziarnistości kontroli, jakiej potrzebujemy.

2

I w zasadzie zobaczyć dwie rzeczy można zrobić:

  1. Albo usunąć te elementy, które nie chcą wystawiać z DataContract poprzez ręczne usunięcie [] DataMember atrybut tych elementów; w takim przypadku WCF nie będzie serializować właściwości out
  2. Definiujesz własne klasy WCF DataContract tylko z tymi, których potrzebujesz, i wymyślisz logikę, aby przekonwertować z twoich jednostek EF na twoją Dane WCF, używając np. coś takiego jak AutoMapper, aby wyeliminować (lub przynajmniej ograniczyć) żmudne operacje przypisania między elementami EF i WCF.

Marc

+0

Dzięki, marc_s. W odniesieniu do punktu 1 powyżej, w jaki sposób ręcznie usunąć atrybut [DataMember] z tych elementów, które są automatycznie generowane z bazy danych? Czy będzie to wymagać ręcznej przeróbki za każdym razem, gdy aktualizuję model z bazy danych? – Malcolm

+0

Niestety, tak, obawiam się, że nie ma automatycznego sposobu tłumienia tych atrybutów [DataMember], o których wiedziałbym. Dlatego pomysł oddzielnych klas WCF, które kontrolujesz w pełni. –