2013-07-30 10 views
21

Właśnie rozpoczął naukę o ASP.NET Web API i mam kilka rzeczy, które są nadal niejasne do mnie:użyciu apicontroller vs OData EntitySetController

  • dlaczego należy używać EntitySetController, która dziedziczy z OData kontrolera zamiast ApiController
  • Dlaczego EF jest często wymieniany w kontekście OData. Wiem, że "reprezentuje" Entity, ale nie rozumiem, dlaczego 2 są połączone. Pierwszy dotyczy warstwy serwisowej, a EF to model.
  • Mam przeczytać i zrozumieć wiele litereture napisane na ten temat, tak tęskniłem, gdy jej najlepsza praktyka

dziękuję, David

+2

To nie jest oparte na opiniach. To nawet nie pachniało jak pytanie oparte na opiniach. Czy ludzie, którzy głosują, aby to zamknąć, robią to: zamknij * po * rozbieżne opinie stają się widoczne w odpowiedziach. –

Odpowiedz

39

dlaczego należy używać EntitySetController, która dziedziczy z OData kontrolera zamiast ApiController

  • Zgadzam się, że jest to mylące i że dokumentacja wydaje się być brakuje (przynajmniej kiedy miał takie samo pytanie jak ty). Sposób, w jaki uspokajałem swoje uczucia, to po prostu czytanie the code. Zachęcam do zrobienia tego samego, ponieważ jest bardzo krótki (skoncentruj się na klasie EntitySetController i jej helpers); nie powinno trwać dłużej niż 5-10 minut od początku (obietnica), a po tym nie będziesz miał żadnych pytań.

    Krótka historia polega na tym, że eliminuje ona pewną podstawę do typowych przypadków (ale kontynuuj czytanie, jeśli chcesz uzyskać lepszy kontekst i opinię).

Dlaczego EF często wymieniane w kontekście OData. Wiem, że "reprezentuje" Entity, ale nie rozumiem, dlaczego 2 są połączone. Pierwszy dotyczy warstwy serwisowej, a EF to model.

  • Ten mylić mnie zbyt nieskończoność, dopóki nie poddał się i spojrzał na pochodzenie OData The WCF Data Services (poprzednio ADO.NET Data Services) oraz OData specifications (podpowiedź, że podstawowe wersje protokołu OData są nadal określone z nagłówkiem o nazwie "DataServicesVersion"). Tam można znaleźć, że OData używa EDM, Entity Data Model, który jest tą samą specyfikacją modelu używaną przez EF i serializuje go w tym samym formacie co EF: CSDL (Konceptualny język definicji schematu). Nie jest to przypadek, WCF Data Services ma podstawowe wsparcie dla EF i chociaż nie wymaga tego, można by powiedzieć, że jego projekt był na nim oparty.

    Należy zauważyć, że usługa danych WCF jest nadal była flagową implementacją OData.

Coś, co jest potencjalnie dużego zainteresowania (przynajmniej było do mnie): W przypadku korzystania z EF ASP.NET Web API i OData rozszerzeń nie ma możliwości (o ile wiem) do udostępnić model między tymi dwoma.

Możesz przejść do następnego punktu, aby uzyskać następną odpowiedź, jeśli nie uważasz, że jest to interesujące.

Na przykład przy korzystaniu z EF w konfiguracji Code-First zazwyczaj tworzymy model oparty w dużym stopniu na konwencjach kodowych i EF System.Data.Entity.DbModelBuilder ("płynny API"). Następnie użyjesz System.Web.Http.OData.Builder.ODataConventionModelBuilder, który zrobi dokładnie to samo, aby skonstruować model OData i osiągnie dokładnie taki sam wynik. W przeszłości udało mi się wydobyć kilka losowych notatek z losowego spotkania z zespołu EF lub zespołu Web API, o którym wspominałem krótko, i o ile pamiętam (nie mogę już znaleźć tego dokumentu), nie planowali poprawy sytuacji. W związku z tym mają teraz dwie różne i niekompatybilne implementacje EDM.

muszę przyznać, że nie miała czasu, aby przejść przez kod obszernie, aby sprawdzić to prawidłowo, ale wiem, że Web API + OData rozszerzenia zależą EdmLib (co zapewnia Microsoft.Data.Edm początkowo opracowany dla WCF Data Services), natomiast EF nie, a zamiast tego używa własnej implementacji System.Data.Entity.Edm. Wiem również, że ich twórcy modeli opartych na konwencjach są różni, jak wyjaśniono powyżej. Staje się to niedorzeczne, gdy używasz EF w konfiguracji DB-First; otrzymasz serializowany model EDM w formacie CSDL w EDMX file, a rozszerzenia OData kontynuują i generują swój własny, zserializowany kod CSDL w czasie wykonywania z kodu CLR (przy użyciu oddzielnych konwencji kodu) wygenerowanego przez EF z początkowego CSDL za pośrednictwem szablonów T4. Twoja głowa się kręci?


Aktualizacja: To largely improved niecałe dwa tygodnie temu (19 lipca), że brakowało mi przykro. (Dzięki RaghuRam Nadiminti.) Nie przejrzałem łaty, ale z przykładowego kodu wydaje się, że sposób w jaki działa to to, że trzeba serializować model do CSDL za pomocą serializera EF EDMX, a następnie deserializować go za pomocą parsera EdmLib, aby był używane przez rozszerzenia OData. Nadal czuje się trochę jak hack w Kodzie EF - Pierwsze ustawienia (przynajmniej kod CLR jest analizowany tylko raz, ale wolałbym, żeby oba komponenty korzystały z tego samego modelu w pamięci). Prawdopodobnie można użyć skrótu przy użyciu scenariusza Model-First lub Database-First, deserializując bezpośrednio plik EDMX wygenerowany przez VS. W tym ostatnim scenariuszu rzeczywiście wydaje się mniej jak hack, ale znowu, jeden model byłby najlepszy. Nie wiem, czy EF przerzuciłoby się na EdmLib, czy też EdmLib przerzuciłby się na model EDM EF, oba projekty są teraz naprawdę mocne, a blokery to nie tylko problemy techniczne. Zespół ASP.NET niestety nie może wiele z tym zrobić AFAICT.



Aktualizacja: Losowo natknął those meeting notes ponownie. Rzeczywiście byli z zespołu EF i wskazują, że nie zamierzają pracować nad EdmLib.


Jednak teraz wierzę, że to wszystko jest dobre. Powodem jest to, że jeśli zamkną wszystkie luki i usunie wszystkie bloki, i wszystko będzie w porządku, ostatecznie znajdą się tam, gdzie są WCF Data Services, czyli w pełni zintegrowane rozwiązanie, w którym programista wstrzykuje kod w potoku przez " Interceptory ".Dla mnie jedynym powodem, dla którego warto tam jechać, jest zapotrzebowanie na oprogramowanie typu open source, ale nawet wtedy myślę, że rozsądniej jest wypróbować program open source WCF-DS.

Pojawia się teraz pytanie: "Ale do czego jest przydatne rozszerzenie Web API + OData?". Dobrze, gdy naprawdę chcesz mieć dwa różne modele do przechowywania danych i usług internetowych. Jest to dobre rozwiązanie, gdy projekt "przechwytujący" nie jest wystarczająco elastyczny, aby można było przetłumaczyć te dwa modele.


Aktualizacja: Na dzień 27 marca 2014 roku, to urzędnik, są one zamiar spróbować zamknąć te luki, deprecating WCF Data Services in the process. Bardzo wczesne rozmowy wspominają o "obsłudze", najprawdopodobniej obsłudze HTTP ASP.NET (zobacz komentarze do ogłoszenia). Wygląda na to, że bardzo mało planowania zostało już w to uwzględnione, ponieważ wciąż burzy mózgów pomysły, aby interfejs API sieci ASP.NET wypełnił przypadki użycia usług danych WCF. Wspomniałem o powyższych przypadkach użycia, w komentarzu do ogłoszenia i this thread (rozpoczęło się kilka dni przed ogłoszeniem).

Wiele innych osób wyraziło bliskie identyczne obawy (ponownie, patrz połączone dyskusje), więc dobrze jest zobaczyć, że nie śniłem o tym wszystkim.

Istnieje pewne niedowierzanie, że ASP.NET Web API można przekształcić w coś użytecznego dla przypadków użycia usług danych w rozsądnym czasie, więc niektórzy ludzie suggested that MSFT reconsider their decision. Kwestia, czy używać ASP.NET do wymagań open source, jest również dyskusyjna: WCF Data Services wkrótce będzie otwarte, jeśli wszystko pójdzie "dobrze", ale nie dzięki wysiłkom rzeczniczym. (Jest to po prostu zrzut źródłowy, nie wiadomo, czy ktoś go w tym momencie utrzyma.)

Z tego, co mogę zebrać, wszystko wskazuje na obniżenie budżetu, a niektórzy ludzie mówią o tym, że jest to wynik całego przedsiębiorstwa "ponowne skupienie", choć wszystko to powinno być zrobione z przymrużeniem oka.

Poza tym istnieje możliwość, że z czasem pojawi się nowe rozwiązanie - jeszcze lepiej niż WCF Data Services lub Web API, jeśli chodzi o API OData. Chociaż obecnie wygląda trochę chaotycznie, zespół MSFT OData otrzymał stosunkowo wcześnie sporo informacji od swoich klientów, więc jest nadzieja (szczególnie, jeśli przyszłe rozwiązanie, jeśli takie istnieje, samo w sobie jest otwarte). Przejście prawdopodobnie będzie bolesne, ale pamiętaj, aby w przyszłości oglądać dyskusje na ten temat.

Nie jestem pewien, czy poświęcę czas na zaktualizowanie tego posta; Chciałem tylko podkreślić, że rzeczy związane z Web API i usługami danych wkrótce ulegną zmianie, ponieważ ta odpowiedź jest od czasu do czasu przegłosowana.



Aktualizacja:RESTier (announcement) wydaje się być wynikiem.


I wreszcie, moim zdaniem (osobiste): OData, mimo że technicznie relaksującego protokół HTTP oparte jest bardzo, bardzo, bardzo zorientowany danych. Jest to absolutnie w porządku (możemy zdefiniować wiele różnych typów interfejsów z HTTP), a ja uważam, że wszystkie dyskusje ServiceStack vs OData są nieistotne (uważam, że działają na różnych warstwach w naszych obecnych, wspólnych architekturach). Niepokojące jest to, że ludzie próbujący tworzyć API oparte na OData działają jak API zorientowany na zachowanie (lub "zorientowany na proces" lub "ServiceStack").Dla mnie konwencje ODDA URI i formaty reprezentacji zasobów (Atom i JSON) zastępują SQL, WCF Data Services "Query Interceptors" and "Change Interceptors" zastępują wyzwalacze DBMS, a OData Actions zastępują przechowywane procedury DBMS. Z tej perspektywy natychmiast zobaczysz, że jeśli logika domeny, którą musisz umieścić za swoim interfejsem OData API, jest zbyt skomplikowana lub mało zorientowana na dane, skończysz z zawiłymi "Akcjami", które nie respektują zasad REST, i podmioty, które nie czują się dobrze. Jeśli potraktujesz swój interfejs OData jako czystą warstwę danych, wszystko będzie dobrze. Możesz ułożyć na nim usługę tak, jakbyś umieścił "warstwę usługi" na bazie danych SQL.

I dlatego nie jestem pewien, czy rozszerzenie Web API + OData jest już tak wspaniałe. Jeśli potrzebujesz zasadniczo różnych modeli, prawdopodobnie Twoja aplikacja nie jest zorientowana na dane (chyba, że ​​po prostu łączysz modele z różnych źródeł lub coś takiego), a OData nie jest dobrym rozwiązaniem. To jest znak, że powinieneś przynajmniej rozważyć Web API sam (z albo SQL albo OData poniżej) albo coś jak ServiceStack.

Na dobre i na złe klienci JavaScript nie mogą rozmawiać SQL na serwerze zdalnym. Być może w przyszłości za pośrednictwem interfejsów API przeglądarki, a może poprzez warianty WebSockets, ale teraz OData jest najbliższą zdalnej warstwie danych, którą każdy może uzyskać dla bogatych klientów JS, którzy mają cienką lub żadną logikę po stronie serwera. OData jest oczywiście używana przez inne typy klientów, ale powiedziałbym, że jest szczególnie przydatna na platformie internetowej po stronie klienta, gdzie rzeczy takie jak Breeze.js lub JayData są OData, co Entity Framework jest dla SQL.

Mam przeczytać i zrozumieć wiele litereture napisane na ten temat, tak tęskniłem, gdy jej najlepsza praktyka

  • Nie martw się, rozejrzałem się, ale don” Sądzę, że każdy naprawdę wie, co robią. Po prostu udawaj jak wszyscy inni, podczas gdy ty rozumiesz ten bałagan.
+0

Świetna odpowiedź. Jedna mała rzecz to to, że API OD API może obsługiwać IEdmModel generowane zewnętrznie. [Ten problem] (https://aspnetwebstack.codeplex.com/workitem/802) jest teraz naprawiony, więc jeśli chcesz wystawić swoją bazę danych tak jak jest, możesz teraz –

+0

Zaktualizowany interpretacją twojej poprawki (świetna robota BTW, mam nadzieję, że dobrze to zrobiłem!). – tne

+0

Dzięki za świetne i długa odpowiedź. (W dobrym tłumaczeniu.)) Kocham twoją odpowiedź na ostatnie pytanie. Hahaha, chociaż mam nadzieję, że to nie jest prawda po kilku latach. =) –

0

Zastosowanie EntitySetController jeśli chcesz utworzyć OData punkt końcowy. Użyj ApiController, jeśli chcesz zwrócić ogólny JSON lub XML lub inny format (np. Używając niestandardowego formatyzatora).

W Web API, EF i OData niekoniecznie są połączone. Możesz zapisać punkt końcowy OData, który nie używa EF. Wiele samouczków Web API używa EF, ponieważ kod EF-pierwszy jest stosunkowo łatwy do pokazania w samouczku. :-)

+0

Dzięki, ale kiedy chcę uzyskać punkt końcowy OData? Na przykład mam klasę "A" i 3 inne klasy, które dziedziczą po A: A1, A2 i A3. Chcę ujawnić operacje CRUD dla A1, A2 i A3. Czy powinienem utworzyć dla każdego z nich (chcę 3 różnych kontrolerów) apiController lub EntitySetController? –

+0

Zazwyczaj potrzebny jest jeden punkt końcowy na "usługę"; to decyzja architektoniczna. Każdy Web API reprezentuje punkt końcowy OData (to co nazywam Web API jest "tym, do którego mapujesz ODataRoute i model EDM do) Model ma wiele elementów (twoje trzy klasy) .Każda jednostka jest kontrolowana przez pojedynczy kontroler OData , prawdopodobnie EntitySetController (który po prostu rozszerza klasę ODataController) . – tne