2009-02-25 5 views
10

W tym temacie wymyśliłem wiele ślepych zaułków. Podobno .NET 3.5 SP1 ma wsparcie dla obiektów ADO.NET Entity Framework w kontraktach WCF. Ale kiedy szukam solidnych informacji na ten temat, nie otrzymuję wielu odpowiedzi. Znalazłem ten jeden fragment w wątku MSDN. Czy ktokolwiek ma z tym jakieś doświadczenie? Co stało się z [DataContract]? Czy to wszystko? Dlaczego jest tak mało materiału na ten temat?Kontrakty WCF z Entity Framework?

To odpowiedź od Tim Mallalieu w Microsoft.

Typy encji generowane w ramach Entity Framework to domyślnie kontrakty danych. Gdybym miał stworzyć prosty model w Entity Designer, taki jak poniżej: Typ jednostki koszyka jest domyślnie DataContract ze wszystkimi właściwościami opisanymi jako elementy danych. Możemy to wykorzystać w usług WCF w następujący sposób:

[ServiceContract] 

public interface IService1 

{ 
    [OperationContract] 
    Cart[] AllCarts(); 
} 



public class Service1 : IService1 

{ 
    public Cart[] AllCarts() 

    { 
     using (MSPetShop4Entities context = new MSPetShop4Entities()) 

     { 
      var carts = from c in context.Carts select c; 
      return carts.ToArray(); 
     } 
    } 
} 

jako żywe są DataContracts można teraz toczyć swoje usługi zgodnie z potrzebami i wysłać te po drugiej stronie drutu.

Odpowiedz

1

Możesz przejść w łatwy sposób i użyć ADO.NET Data Services.

+0

W końcu zrobiłem dokładnie to. Mam nadzieję, że to nie pomyłka na dłuższą metę. Minusem, jaki widzę do tej pory, jest to, że zakończyłem implementację wzorca repozytorium po stronie klienta, a nie po stronie modelu. Nie jestem z tego powodu szczęśliwy i prawdopodobnie będę musiał później dokonać refaktoryzacji. – Weej

+0

Niebezpieczeństwo ADO.NET Data Services polega na tym, że trudno jest zastosować podejście DDD. Usługi ADO.NET Data Services należy traktować tylko jako: usługi danych. Jeśli potrzebujesz silniejszego zestawu usług modelowych, musisz go utworzyć osobno. –

+0

Nawet z najnowszą wersją ADO .NET Data Services i EFCF 4.1 nadal jest poważnie ograniczona. Na przykład żaden z operatorów agregujących z LINQ nie jest obsługiwany, w tym 'Distinct()'. Jeśli potrzebujesz czegoś więcej niż funkcji CRUD, powinieneś trzymać się z dala od usług danych. – Yuck

6

Polecam, aby nie zwracać bezpośrednio jednostek. Niestety, Microsoft zdecydował się włączyć dane specyficzne dla wdrożenia w ramach DataContract dla podmiotów. To nie będzie współdziałać z innymi platformami i jest rzeczą, która może nie współpracować nawet między wersjami .NET.

Zamiast tego zalecam, abyś stosował się do wzorca obiektów przenoszenia danych i tylko zwracał klasy POCO, które są kopiami danych w jednostkach, bez zachowania. Możesz zwrócić listę takich klas, aby reprezentować tabelę, itp.

+0

Zastanawiałem się nad tym, ale umysł gniewa się na ile pracy może to spowodować. Na pierwszy rzut oka powyższy prosty kod nie zaciera rozbieżności. Jeśli mam przyjąć EF, to nie jestem za grosza, za funta? Innymi słowy, jestem już poza terytorium POCO. Nie? – Weej

+0

OK John, przepraszam, ominąłem twój punkt widzenia. Mówisz, że zwracany obiekt zawiera oprócz "prostych danych" inne rzeczy. To nie jest dobrze. Czy jest jakiś dobry sposób, w jaki wymyśliłeś wygenerowanie oświadczeń kontraktowych DTO? – Weej

+0

Część mnie chce, aby MS oferowało podzbiór WCF, który jest mniej interoperacyjny, ale więcej Data Entity, Linq, itp. Przyjazne, ale wtedy coś takiego nadal dodaje sprzężenie, którego nie jestem pewien jest dobrym pomysłem ... –

3

Założenie "dzielenie interfejsów, a nie typ" zakłada, że ​​nie jesteś właścicielem obu końców drutu i/lub piszesz publicznie Serwis internetowy. WCF może być używany (i jest używany) w kontekstach, w których jest to zdecydowanie , a nie. Wiele wielowarstwowych architektur przedsiębiorstw ma warstwę aplikacji z frontem WCF, co ułatwia między innymi równoważenie obciążenia. W takich przypadkach jest to całkowicie ważne, aby dzielić się typem, a w rzeczywistości jest pożądane.

1

Niektóre bardziej szczegółowo w odpowiedzi na komentarze:

Istnieje kilka problemów związanych z klas generowanych przez EF. Patrzę teraz na przykład AdventureWorks z SalesOrderHeader i SalesOrderDetail. Atrybut SalesOrderDetail ma właściwości "SalesOrderHeader" i "SalesOrderHeaderReference", obie oznaczone jako DataMembers. Wygląda to jak błąd, ponieważ właściwość "SalesOrderHeader" jest również oznaczona [XmlIgnore] i [SoapIgnore].

Zastanów się także, czy chcesz najpierw przekształcić link do nadrzędnego SalesOrderHeader. Poza tym, co dokładnie powinno być serializowane? SOAP nie obsługuje odwołań w sposób interoperacyjny.

Wreszcie klasy bazowe podmiotów to także kontrakty danych. Jednak nie mają one nic wspólnego z danymi, które powracają - są czysto artefaktem implementacji.

Krótko mówiąc, Microsoft spieprzył to. Oni tego nie przemyślali.

O sposobach generowania klas DTO sugeruję przejrzenie różnych narzędzi do generowania kodu, takich jak CodeSmith. Możesz napisać kod, aby sam to zrobić; Zrobiłem to na poprzedniej pozycji.Fajną rzeczą w generowaniu DTO jest to, że zyskujesz także możliwość generowania metod tłumaczenia z DTO.

Co do narzutu, obciążenie związane z przenoszeniem niektórych danych w pamięci jest niczym w porównaniu z czasem potrzebnym na przesłanie danych przez sieć!