In dem Artikel „ADO.NET Data Services - Der REST Anbieter
für Modelle“ wurde geschildert, wie einfach O/R-Modelle, als Web-Service mit
REST Funktionalität zur Verfügung gestellt werden können. Dabei wurde ein
Entity-Model von Entity-Framework verwendet. Der Test von REST wurde mittels
Browser (URL) Demonstriert.
Dieser Artikel wird Demonstrieren, wie der Web-Service von
ADO.NET Data Service mittels LINQ auf Clients konsumiert wird. Dafür wird das
Projekt aus dem Vorbericht verwendet: ADONETExample
Du gehörst zu mir!
Der Solution wird jetzt ein weiteres Projekt, der für den
Client steht, hinzugefügt. Als Anwendung reicht eine einfache
Consolen-Anwendung, die den Namen: ADONETExample.Client,
bekommt.
Abb.1.1. – Neuen Client „ADONETExample.Client“ hinzufügen.
Dann muss dem Client eine Reference vom Web-Service
mitgeteilt werden. Dazu macht man ein rechtsklick auf „References“ und wählt
„Add Service Reference…“.

Abb.1.2 – Service Referenz auf den
Web-Service
Anschließend wird mittels „Discover“ automatisiert in der
Solution nach Web-Services gesucht. Der Namespace wird hier auf: ServiceReference, ergänzt.

Abb.1.3 – Web-Service auswählen
LINQ-2-ADO.NET-Data-Service
Wenn der Web-Service im Client Referenziert ist, möchte ich
kurz einen Einblick unter die Hauben machen. Im Solution-Explorer gibt es oben
ein kleines Icon mit „Show All Files“, nun werden zu dem eben erzeugen
Service-Reference weitere Daten angezeigt. Die Datei service.edmx ist ein kleines Abbild vom Entity-Model das unter ADONETExample.WebDAL.Model liegt.
Interessant ist auch der Inhalt von Reference.cs
unter Reference.datasvcmap. Der
Inhalt spiegelt dieselben Entities von Server auf Client-Seite ab (siehe
Abb.1.4). Es werden demnach die Regeln und Standards dem Client so zur
Verfügung gestellt. Bei einem üblichen Web-Service, werden die Definitionen im
WSDL-Standard (XML) beschrieben (siehe Abb.1.5).

Abb.1.4 – Web-Service im Detail

Abb.1.5 – Herkömlicher Web-Service
mit dem WSDL-Standard
Um auf die Entities mit LINQ Dynamisch zugreifen zu können,
muss erst unser Entity-Model vom Web-Service Instanziiert werden. Dazu ist der
Name: NorthwindEntities gleich
geblieben. Der Konstruktor von NorthwindEntities
verlangt ein URI. Ein URI ist gleichermaßen wie eine URL, nur mit dem
Unterschied, das ein URI als einzigartig gelten muss. Bei einer URL kann sich
jederzeit etwas an der Adresse ändern (z.B. Subdomains). Um die genaue Adresse
beim Entwickeln feststellen zu können, muss der Web-Service manuell im Browser
kurz geöffnet werden. Das kann ganz einfach mittels Rechtsklick auf die Datei: WebDataService.svc und „View in
Browser“. Im Browserkopiert man die Adresse und übergibt diese einer neuen
URI-Instanz, die dann mit den NothwindEntities instanziiert werden kann (siehe
Abb.1.6.).

Abb.1.6 – NorthwindEntities mit
URI Instanziieren
Jetzt kann wie gewohnt eine LINQ abfrage ausgeübt werden.
Hier soll nach einer ID mit „ALFKI“ unter Customers abgefragt werden. Die LINQ-Abfrage
dazu ist sehr einfach und selbsterklärend.
Abb.1.7 – LINQ-Abfrage einer
Customer ID
Die generierte LINQ-Abfrage muss man nun als DataServiceQuery
Instanziieren, damit die Abfrage durch Asynchrone-Kommunikation erweitert wird
(siehe, Abb.1.8.). Die Klasse DataServiceQuery steht im Namespace:
System.Data.Services.Client, zur Verfügung.

Abb.1.8 – LINQ-Abfrage in DataServiceQuery
instanziieren
Wie bereits erwähnt, findet eine Web-Service-Kommunikation
immer Asynchron statt. Das bedeutet, es muss jetzt eine Anfrage an den
Web-Service gestellt werden, wenn es eine Antwort gibt, soll ein Event
dementsprechend eine Methode aufrufen. Dafür ist beim dataServiceQuery-Objekt
eine Methode mit BeginExecute (Starte Anfrage), womit beim ersten Parameter
diese „aufzurufenden“ Methode definiert wird (OnLoadComplete).
Der zweite Parameter benötigt eine eigene Instanz von dataServiceQuery. Am Ende
soll die Console einfach warten mit Consolte.ReadKey(),
sonst beendet sich das Fenster von selbst.
Abb.1.9 –DataServiceQuery
Asynchrone-Kommunikation starten.
Wenn der Web-Service anschließend Antwortet, wird die
Methode OnLoadComplete aufgerufen.
Die Methode bekommt dann alle Informationen von Server über den Parameter result mitgeteilt. Diese muss allerdings
erst einmal geformt werden. Dazu wird der Asynchrone-Status wieder als
dataServiceQuery-Objekt instanziiert. Danach steht die Methode EndExecute bereit. Die das Komplette
Ende des Parameters result in ein
IEnumberable-Objekt zurück gibt.
Abb.1.10 –Asynchrone-Kommunikation
empfangen.
Das IEnumberable-Objekt hat jetzt alle weiteren
Informationen erhalten und kann mit einer Foreach-Schleife ausgelesen werden.
Abb.1.11 – Mit einer
Foreach-Schleife durchs Objekt.
Damit der Code nun ausgeführt werden kann, muss
sichergestellt sein, dass die Consolen-Anwendung auch als Startprojekt
ausgewählt wurde. Das Aktiviert man mit
einem rechtsklick auf „ADONETExample.Client“ und auf „Set as StartUp Project“.
Das Testen vom Code kann nun mit [F5] gestartet werden.
Abb.1.12 –Ausgabe auf der Console.
Fazit
ADO.NET Data Services sind für ein einfaches CRUD (Create, Read, Update und Delete) geradezu ideal.
Für jede weitere Logik müssen wohl zusätzliche Web-Services verwendet werden.
Wie bereits von Robert Mühsig beim letzten Blog-Eintrag Kommentiert, arbeitet
Microsoft bereits an einer erweiterten Variante der ADO.NET Data Services, dem
Projekt .NET RIA Services. Bei einem persönlichen Test und genaueren Analyse
der .NET RIA Services, möchte ich kurz mein Statement dazu geben: Die
Web-Service Kommunikation soll vereinfacht werden, da hier keine weiteren
Methoden für eine Asynchrone Verbindung erstellt werden müssen. Bestimmte Logik
auf dem Server wird auch auf dem Client zur Verfügung gestellt. Das wird
bestimmt Sinnvoll, wenn zum Beispiel Silverlight 3 Out-of-the-Browser Offline
benutzbar seien soll. Desweiteren konnten keine wirklichen Vorteile
festgestellt werden. Es gab hier genauso wenige Möglichkeiten die Business-Logik
bei der Bereitstellung der Daten via REST unterzumischen. Die derzeitige Preview-Version funktionierte allerdings nicht einwandfrei bei mir. Beim
Build-Prozess wird die jeweilige Logik aufgeteilt und konnte aber vom Client nicht
gefunden werden. Ich sage daher Abwarten, derzeit gibt es dadurch keine
wirklichen Vorteile. Es gibt dennoch für die ADO.NET Data Service einen
möglichen aber nicht sauberen Weg die Business-Logik unterzuschieben. Daher zum
Fazit: Gemeinsam mit der Verwendung von LINQ der automatisch die REST abfragen
generiert und dem Data-Binding Unterstützung, ist das ADO.NET Data Service für das
einfache CRUD sehr angenehm und zu Empfehlen.
Wenn ihnen der Artikel gefallen hat oder er für sie hilfreich war, bitten "kicken" sie ihn.
