App-Entwicklung unter SharePoint: Table Joins

Joining SharePoint content für SQL Programmierer. Was geht und was nicht geht.

»Enttäuschung ist mir eine Beglückung, denn zuvor war ich getäuscht, danach ist die Täuschung aufgehoben.«
(Horst Eckert a.k.a. Janosch)

Wer Jahre mit SQL verbracht hat, und dann auf einmal SharePoint Listen und ContentTypes vor sich hat, sollte auf eine Lehrstunde gefaßt sein. Aus der SQL-Welt sind wir es gewohnt, selbst Tabellen, die in unserer Datenbank in keiner durch Constraints definierten Verbindung stehen, frei und je nach Anforderung neu miteinander zu verknüpfen. Manche mögen bei solchen Aktivitäten – vielleicht nicht ganz zu Unrecht – die Qualität des Datenbankdesigns in Frage stellen.
Für jene strengen Gemüter gibt es gute Nachrichten: Wer sich die gegenseitigen Abhängigkeiten und Bezüge seiner Daten nicht vor dem Bau seiner SharePoint Listen und ContentTypes gut überlegt, wird mit CAML – dem Äquivalent zu SQL bei SharePoint – nur wenig Freude haben. Gleich vorweg: Wer bei SharePoint nicht schon beim Datenbankdesign Relationen definiert, wird sich später seine Verknüpfungen nach einzelnen REST-Abfragen auf die beteiligten Listen/ContentTypes selbst zusammenbauen müssen.
Hier hört die Ähnlichkeit aber auch schon auf.
Verwandtschaften
Eine SharePoint “List” mit ihrem zugeordneten “ContentType” ist konzeptionell verwandt mit einem SQL Table.
Ein SharePoint “Lookup” Feld ist konzeptionell verwandt mit einem SQL Foreign Key Constraint.
Hier hört die Ähnlichkeit aber auch schon auf.
“Lookup” ist das SharePoint Zauberwort für Table-Joins
“Lookup” ist das SharePoint Zauberwort für Table-Joins
Während bei einer SQL-Abfrage prinzipiell jede Tabelle mit jeder anderen Tabelle über beliebige Spalten verknüpft werden kann, ist ein SharePoint Join immer und grundsätzlich an solche Relationen gebunden, die bereits durch Lookup Felder etabliert sind.
In die SQL-Welt übersetzt hieße das: Table-Joining nur über die bereits in der Datenbank definierten Foreign Keys Constraints.
Für moderne WebParts aufbauend auf dem SharePoint Framework (SPFx) und Deployment von Features (Lists, ContentTypes, Columns) als Teil des Solution-Deployments bedeutet das: Über mögliche Join-Operations wird bereits beim XML-Design der Site columns, Site content types und Site lists entschieden.
Option 1: Database first.
Und so geht’s. Option 1: Database first.
Mit dieser Option wird die Ergebnistabelle bereits bei der Feature-Implementierung vorbereitet. Nach SQL übersetzt: Datenbankseitig wird ein View über die primäre Tabelle und deren Referenzen erzeugt, und eine Abfrage auf diesen View braucht sich um das Joining nicht mehr zu kümmern. Table-Joins erscheinen für den Abfragenden vollständig transparent.
Implementierung:
Für den primären ContentType wird eine Lookup Column definiert, die auf den sekundären ContentType verweist. SharePoint realisiert dies intern immer über den Wert der ID-Column des sekundären ContentTypes. In SQL-Sprache: Die auf die sekundäre Tabelle verweisende Spalte der primären Tabelle wird mit einem Foreign Key Constraint an die ID-Spalte der sekundären Tabelle gebunden.
Für alle weiteren Spalten der sekundären Tabelle, die in der Ergebnistabelle benötigt werden, wird jeweils eine sekundäre Lookup-Column definiert, die auf die primäre Lookup-Column verweist.
Schema-Definition für Option 1: Database first.
Schema-Definition für Option 1: Database first.
Option 2: Code first.
Und so geht’s. Option 2: Code first.
Mit dieser Option werden alle weiteren Spalten, die aus der sekundären Tabelle benötigt werden, zur Abfragezeit durch CAML-Code deklariert.
Auch für diese Option 2 gilt: Eine Relation zwischen primärer und sekundärer List/ContentType wird Feature-seitig über eine Lookup column hergestellt. Existiert eine solche Relation nicht, kann eine Zusammenführung von Daten aus mehreren Lists/ContentTypes nicht durch eine einzelne Datenbankabfrage, sondern nur programmseitig über mehrere Einzelabfragen realisiert werden.
Implementierung:
Wie bei Option 1 wird für den primären ContentType eine Lookup Column definiert, die auf den sekundären ContentType verweist. Die Definition der weiteren Spalten, die in der Ergebnistabelle benötigt werden, erfolgt jedoch nicht bei der Feature-Definition, sondern wird erst zur Abfragezeit über CAML-Code dynamisch vorgenommen.
CAML-Definition für Option 2
Die Namen der “ProjectedFields” können jetzt wie bei Option 1 der Liste der abgefragten hinzugefügt werden.
0 Antworten

Hinterlassen Sie einen Kommentar

Wollen Sie an der Diskussion teilnehmen?
Feel free to contribute!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.