Freigeben über


Entitätsbeziehungen

GraphQL Abfragen können verwandte Objekte und deren Felder durchlaufen, sodass Sie mit nur einer Abfrage folgendes schreiben können:

{
  books
  {
    items {
      id
      title    
      authors {
        items {
          first_name
          last_name
        }
      }
    }
  }
}

Zum Abrufen von Büchern und deren Autoren.

Damit diese Möglichkeit funktioniert, muss der Daten-API-Generator wissen, wie die beiden Objekte miteinander verbunden sind. Der relationships Abschnitt in der Konfigurationsdatei enthält die erforderlichen Metadaten, damit diese Funktion ordnungsgemäß und effizient funktioniert.

Konfigurieren einer Beziehung

Unabhängig davon, welche Datenbank Sie mit dem Daten-API-Generator verwenden, müssen Sie den Daten-API-Generator explizit darüber informieren, dass ein Objekt mit einem anderen verknüpft ist. Es gibt drei Arten von Beziehungen, die zwischen zwei Entitäten eingerichtet werden können:

1:n-Beziehung

Eine 1:n-Beziehung ermöglicht einem Objekt den Zugriff auf eine Liste verwandter Objekte. Beispielsweise kann eine Buchreihe den Zugriff auf alle Bücher in dieser Reihe ermöglichen:

{
  series {
    items {
      name
      books {
        items {
          title
        }
      }
    }
  }
}

Wenn Fremdschlüssel vorhanden sind, die die Beziehung zwischen den beiden zugrunde liegenden Datenbankobjekten unterstützen, müssen Sie nur den Daten-API-Generator mitteilen, dass Sie eine solche Beziehung verfügbar machen möchten. Mit dab CLI:

dab update Series --relationship books --target.entity Book --cardinality many 

Dadurch wird die series Entität aktualisiert, die im Beispiel verwendet wird:

"Series": {
  "source": "dbo.series",
  ...
  "relationships": {
    "books": {
      "target.entity": "Book",
      "cardinality": "many"    
    }
  }
  ...
}

Unter dem -Element wird ein relationships neuer Schlüssel hinzugefügt: books. Das -Element definiert den Namen, der für das feld GraphQL verwendet wird, um in diesem Fall vom series -Objekt zum in target.entityBook definierten Objekt zu navigieren. Dies bedeutet, dass in der Konfigurationsdatei eine Entität namens vorhanden Book sein muss.

Die cardinality Eigenschaft teilt dem Data API-Generator mit, dass in jeder Reihe viele Bücher vorhanden sein können, sodass das erstellte GraphQL Feld eine Liste von Elementen zurückgibt.

Diese Eigenschaft ist alles, was Sie benötigen. Beim Start erkennt der Daten-API-Generator automatisch die Datenbankfelder, die verwendet werden müssen, um die definierte Beziehung aufrechtzuerhalten.

Wenn Sie keine Fremdschlüsseleinschränkung haben, die die Datenbankbeziehung aufrechterhalten soll, kann der Daten-API-Generator nicht automatisch ermitteln, welche Felder verwendet werden. Um den Daten-API-Generator zu informieren, welche Felder die beiden Entitäten in Beziehung setzen, müssen Sie sie manuell angeben. Sie können sie mit der CLI angeben, indem dab updateSie verwenden:

dab update Series --relationship books --target.entity Book --cardinality many  --relationship.fields "id:series_id"

Mit der Option relationship.fields können Sie definieren, welche Felder von der entität verwendet werden, die aktualisiert wird (Series) und welche Felder von der Zielentität (Book) verwendet werden, um die Daten von einer Entität mit der anderen zu verbinden.

Im vorherigen Beispiel wird das id Datenbankfeld der Series Entität mit dem Datenbankfeld series_id der Book Entität abgeglichen.

Die Konfiguration enthält auch diese Informationen:

"Series": {
  "source": "dbo.series",
  ...
  "relationships": {
    "books": {
      "cardinality": "many",
      "target.entity": "Book",
      "source.fields": ["id"],
      "target.fields": ["series_id"]
    }    
  }
  ...
}

n:1-Beziehung

Eine m:1-Beziehung ähnelt der 1:n-Beziehung mit zwei Hauptunterschieden:

  • ist cardinality auf festgelegt. one
  • Das erstellte GraphQL Feld gibt einen Skalar und keine Liste zurück.

Nach den zuvor verwendeten Book Series-Beispielen kann ein Buch in nur einer Reihe enthalten sein, sodass die Beziehung mit dem folgenden DAB CLI-Befehl erstellt wird:

dab update Book --relationship series --target.entity Series --cardinality one

Dadurch wird diese Konfiguration generiert:

"Book": {
  "source": "dbo.books",
  ...
  "relationships": {       
    "series": {
      "target.entity": "Series",
      "cardinality": "one"
    }
  }
}

Dies wiederum ermöglicht eine GraphQL Abfrage wie in diesem Beispiel:

{
  books {
    items {
      id
      title    
      series {
        name
      }
    }
  }
}

Wobei jedes Buch auch die Reihe zurückgibt, zu der es gehört.

m:n-Beziehung

Viele zu viele Beziehungen können als ein Paar von 1:n- und n:1-Beziehungen betrachtet werden, die zusammenarbeiten. Ein Autor kann sicherlich mehr als ein Buch schreiben (eine 1:n-Beziehung), aber es stimmt auch, dass mehr als ein Autor an demselben Buch arbeiten kann (eine m:n-Beziehung).

Der Daten-API-Generator unterstützt diese Art von Beziehung nativ:

  • Verwenden eines 1:n-/n-1-Beziehungspaars.
  • Verwenden eines Verknüpfungsobjekts.

Verwenden eines 1:n-/n-1-Beziehungspaars

Eine geschäftliche Anforderung, die wahrscheinlich vorhanden sein wird, besteht darin, nachzuverfolgen, wie Lizenzgebühren zwischen den Autoren eines Buches aufgeteilt werden. Um eine solche Anforderung zu implementieren, sind eine dedizierte Entität, die einen Autor miteinander verknüpft, ein Buch und die zugewiesenen Lizenzgebühren erforderlich. Daher werden drei Entitäten benötigt:

  • authors, um biografische Details von Autoren darzustellen.
  • books, um Buchdaten wie Titel und International Standard Book Number (ISBN) darzustellen.
  • books_authors , um Daten darzustellen, die sich sowohl auf ein Buch als auch auf den Autor beziehen, z. B. den Prozentsatz der Lizenzgebühren, die ein Autor für ein bestimmtes Buch erhält.

Die drei Entitäten können mithilfe des folgenden Diagramms visualisiert werden.

Diagramm, das die m:n-Beziehung zwischen Autoren, books_authors und Büchern zeigt.

Wie sichtbar, gibt es zwei bidirektionale Beziehungen:

  • 1:n/n-Beziehung zwischen authors und books_authors
  • 1:n/n-Beziehung zwischen books und books_authors

Um ein solches Szenario ordnungsgemäß mit DAB zu behandeln, müssen nur die zugehörigen Entitäten und Zuordnungen in der Konfigurationsdatei erstellt werden. Angenommen, die Book Entität und Author befinden sich bereits in der Konfigurationsdatei:

dab add BookAuthor --source dbo.books_authors --permissions "anonymous:*"

Um die neue Entität hinzuzufügen, führen Sie aus dab update:

dab update Book --relationship authors --target.entity BookAuthor --cardinality many --relationship.fields "id:book_id"
dab update Author --relationship books --target.entity BookAuthor --cardinality many --relationship.fields "id:author_id"

Führen Sie erneut aus, dab update um die Beziehungen zur neu erstellten BookAuthor Entität hinzuzufügen:

dab update BookAuthor --relationship book --target.entity Book --cardinality one --relationship.fields "book_id:id"
dab update BookAuthor --relationship author --target.entity Author --cardinality one --relationship.fields "author_id:id"

So fügen Sie die Beziehungen von BookAuthor zu Book - und Author -Entitäten hinzu. Mit der bereitgestellten Konfiguration kann DAB geschachtelte Abfragen wie das folgende Beispiel verarbeiten:

{
 authors {
    items {
      first_name
      last_name      
      books {
        items {
          book {
            id
            title
          }
          royalties_percentage
        }
      }      
    }
  }
}

Wo Sie bitten, alle Autoren zurückzugeben, das Buch, das sie geschrieben haben, zusammen mit den damit verbundenen Lizenzgebühren.

Verwenden eines Verknüpfungsobjekts

Der im vorherigen Abschnitt beschriebene Prozess funktioniert hervorragend, wenn auf alle Entitäten, die an den M:n-Beziehungen beteiligt sind, über GraphQL zugegriffen werden muss. Dieses Szenario ist nicht immer der Fall. Wenn Sie z. B. keine Lizenzgebühren nachverfolgen müssen, bringt die BookAuthor Entität dem Endbenutzer keinen wirklichen Wert. Die Entität wurde nur verwendet, um ihren Autoren Bücher zuzuordnen. In relationalen Datenbanken werden m:n-Beziehungen mithilfe einer solchen dritten Tabelle erstellt, die die Tabellen verknüpft, die an der m:n-Beziehung teilnehmen:

Diagramm, das eine weitere m:n-Beziehung zwischen Autoren, books_authors und Büchern zeigt.

Im Diagramm sehen Sie, dass es eine Tabelle namens books_authors gibt, die Autoren mit ihren Büchern und Büchern mit ihren Autoren verknüpft. Diese Verknüpfungstabelle muss nicht für den Endbenutzer verfügbar gemacht werden. Die Verknüpfungstabelle ist nur ein Artefakt, um die m:n-Beziehung zu ermöglichen, aber der Daten-API-Generator muss seine Existenz kennen, um sie ordnungsgemäß verwenden zu können.

Die DAB-CLI kann verwendet werden, um die m:n-Beziehung zu erstellen und auch das Verknüpfungsobjekt zu konfigurieren (stellen Sie sicher, dass Sie alle im vorherigen Abschnitt erstellten Beziehungen entfernen und nur mit der Book Entität und Author beginnen, ohne dass bereits eine Beziehung zwischen ihnen konfiguriert ist):

dab update Book --relationship authors --target.entity Author --cardinality many --relationship.fields "id:id" --linking.object "dbo.books_authors" --linking.source.fields "book_id" --linking.target.fields "author_id" 

Dadurch wird die JSON-Konfigurationsdatei wie in diesem Beispiel aktualisiert:

"Book": {
  "source": "dbo.books",
  ...
  "relationships": {       
    "authors": {
      "cardinality": "many",
      "target.entity": "author",
      "source.fields": [ "id" ],
      "target.fields": [ "id" ],
      "linking.object": "dbo.books_authors",
      "linking.source.fields": [ "book_id" ],
      "linking.target.fields": [ "author_id" ]
    }
  }
}

Die Konfiguration teilt DAB mit, dass Sie ein authors Feld in der Entität hinzufügen möchten, das Book den Autoren des Buchs zugriff ermöglicht. authorskann seinmany, sodass eine Liste von Autoren zurückgegeben wird, wenn die GraphQL Abfrage auf das authors Feld zugreift. Diese Beziehung definiert das Navigieren vonBüchern zu Autoren: Die Datenbankfelder, die zum Navigieren von Büchern zu ihren Autoren verwendet werden, werden in der source.fields für das Buch und in der target.fields für die Autoren definiert, ähnlich wie die zuvor in diesem Artikel beschriebene 1:n- oder n:n-Beziehung.

Diese Beziehung ist eine m:n-Beziehung, sodass es keine direkte Verbindung zwischen den beiden Entitäten gibt und daher verwendet linking.object werden muss. Im Beispiel wird die Datenbanktabelle dbo.books_authors als Verknüpfungsobjekt verwendet. Wie das verknüpfende Objekt Bücher mit ihren Autoren verbinden kann, ist in den linking.source.fields Eigenschaften und linking.target.fields definiert. Die erste teilt DAB mit, wie die Quellentität - die Book - mit dem likenden Objekt verbunden ist, und die zweite, wie das verknüpfende Objekt mit der Zielentität verbunden ist, Author im Beispiel.

Um zu verstehen, wie die bereitgestellten Informationen verwendet werden, können Sie diese Beispiel-äquivalente Abfrage verwenden:

select * 
from dbo.books as b
inner join dbo.books_authors as ba on b.id = ba.book_id 
inner join dbo.authors a on ba.author_id = a.id 

Mit der bereitgestellten Konfiguration kann DAB GraphQL wie in diesem Beispiel verstehen:

{
  books {
    items {
      id
      title
      authors {
        items {
          first_name
          last_name
        }
      }
    }
  }
}

Wo Sie Bücher und deren Autoren bekommen möchten.

Um die Navigation von Author zu Bookermöglichen, können dieselben Prinzipien angewendet werden, indem die Konfiguration mit dem folgenden Befehl aktualisiert wird:

dab update Author --relationship books --target.entity Book --cardinality many --relationship.fields "id:id" --linking.object "dbo.books_authors" --linking.source.fields "author_id" --linking.target.fields "book_id" 

Definiert eine m:n-Beziehung zwischen der Author Entität und der Book Entität unter Verwendung des Verknüpfungsobjekts dbo.books_authors im Hintergrund.