2010-10-13 6 views
20

Ich versuche, herauszufinden, wie das Äquivalent zu erreichen:Wie verwende ich OData Expand wie einen SQL-Join?

select * 
from Users u 
inner join Comments c on c.UserId = u.Id 
where Id = 1569 

(Tabellen-Aliases für eine bessere Lesbarkeit SQL)

... auf dem Stackoverflow OData-Endpunkt. Wie würde diese URL aufgebaut werden? Ich sehe die Dokumentation für Expand bei OData.org und ich hätte gedacht, dass es so etwas wie aussehen würde:

https://odata.sqlazurelabs.com/OData.svc/v0.1/rp1uiewita/StackOverflow/Users?$Expand=Comments&$filter=UserId eq 1569 ist aber nicht richtig.

In Linq, wäre es diese (glaube ich), aber Mitglied werden nicht unterstützt:

Users.Where(u=>u.Id==1569).Join(Comments, u=>u.Id, c=>c.UserId, (a,b)=>a.Id==b.UserId)

Ich brauche nicht diese streng in Linq, um herauszufinden, versuche ich gerade um herauszufinden, wie die Abfrage-URL erstellt wird. Wie kann ich das SQL-Join-Prädikat in eine OData-URL übersetzen und dies in einem Aufruf tun?

+9

Dies scheint die 1 Millionste Frage von Stack Overflow gewesen zu sein, herzlichen Glückwunsch! – jwaddell

+2

Nun, wenn Sie Fragen zählen, die nicht gelöscht wurden, bis diese Frage gestellt wurde. – jjnguy

+0

@jwaddell Ich legte eine Millisekunde nach der eigentlichen millionsten Frage ein, also denke ich, das ist 1e6 + 1 –

Antwort

15

Der richtige Weg, diese wäre so etwas wie zu tun:

http://odata.stackexchange.com/stackoverflow/atom/Users(1569)?$expand=Comments 

Das Problem ist, dass es scheint keine Benutzer in der Datenquelle zu sein (weiß nicht, warum), so dass die obige Abfrage zurückkehren a 404. Aber es ist die richtige Syntax.

Die Idee ist, dass, wenn Sie Informationen über nur einen Benutzer wollen Sie "navigieren" zu ihm mit dem /Users(1569) (die Sachen in Parethesis ist der Primärschlüssel des Entitätssatzes). Wenn Sie alle Kommentare hinzufügen möchten, fügen Sie einfach $expand=Comments hinzu. Wenn Sie nur die Kommentare und nicht die Informationen über den Benutzer möchten, können Sie /Users(1569)/Comments tun.

Beachten Sie, dass der Dienst, den Sie verwendet haben, keine Navigationseigenschaften definiert, daher funktioniert das oben Gesagte nicht, da "Joins" nicht wirklich unterstützt werden. Für den ODATA-Stackexchange-Endpunkt sind jedoch die Navigationseigenschaften definiert.

Grundsätzlich sind die Joins auf dem Server/Service definiert, so dass der Client nicht wissen muss, welche Spalte ein Fremdschlüssel für welchen Primärschlüssel ist.

Es hilft auch bei Datenquellen, die relationale Datenbanken nicht als Speicher verwenden, da sie nicht gezwungen werden, gefälschte Fremdschlüssel zu erstellen.

Sie können weitere "Ebenen" des Graphen erweitern. Wenn die in der Erweiterung zurückgegebene Entität auch weitere Navigationseigenschaften definiert, können Sie eine durch Kommas getrennte Liste der Navigationseigenschaften angeben.

Hier ist ein Beispiel für einen erfundenen Dienst, beachten Sie, dass dies jeden Kunden in der Sammlung erweitert, die einem Mehrfachbeitritt ähnelt.

.../Customers?$expand=Orders,OrderDetails 
+0

Wie drückt diese URL-Syntax die Beziehung zwischen Users.Id und Comments.UserId aus? Wie kennen diese Felder voneinander? Wird diese Beziehung Server-Seite identifiziert? –

+2

In OData gibt es keine "Joins" wie in SQL Server. Beziehungen werden als sogenannte "navigation" -Eigenschaften dargestellt. Grundsätzlich Eigenschaften mit einem Wert von einer oder mehreren Entitäten (oder Links zu diesen Entitäten). Also, wenn die Daten durch eine SQL-Tabelle gesichert werden, muss der genaue Join definiert werden Ich habe die obige Antwort aktualisiert, um festzustellen, dass das Beispielmodell nicht über die Navigationseigenschaften verfügte, aber das auf Stackexchange hat tatsächlich diese. –

+0

Ich bin besorgt über Ihre zusätzliche Notiz, ob der Erfolg oder Misserfolg von Diese Abfrage basiert auf der Implementierung von OData? Wird diese Abfrage nicht durch die Spezifikation garantiert? –