Definieren von Datenmodellen für Fabric Apps

Fabric Apps verwendet TypeScript-Dekoratoren zum Definieren von Datenmodellen, die Datenbanktabellen und APIs generieren. Sie definieren jede Entität als Klasse, die mit @entity()versehen ist, Fügen Sie Felddekortoren für Datentypen hinzu und ordnen Sie Beziehungen zwischen Entitäten zu.

Anweisungen zur Autorisierung und Zugriffssteuerung finden Sie unter Definieren von Datenberechtigungen.

Voraussetzungen

  • Ein Fabric Apps-Projekt, das mit npm create @microsoft/rayfin@latest erstellt oder mit npx rayfin init initialisiert wurde.
  • Grundlegendes Verständnis von TypeScript-Klassen und Dekorateuren.

Definieren einer Entität

Um ein Datenmodell zu erstellen, fügen Sie den @entity() Dekorateur einer TypeScript-Klasse hinzu. Importieren Sie dann die erforderlichen Dekoratoren aus @microsoft/rayfin-core:

import { entity, uuid, text, date } from '@microsoft/rayfin-core';

@entity()
export class Todo {
  @uuid() id!: string;
  @text() title!: string;
  @text({ optional: true }) description?: string;
  @date() createdAt!: Date;
  @date() updatedAt!: Date;
}

Diese Entität generiert eine Todo Tabelle mit Spalten für id, title, , description, createdAtund updatedAt.

Primärschlüssel

Jede Entität verwendet ein UUID-Feld string , das als Primärschlüssel bezeichnet wird id . Wenn Sie id nicht explizit deklarieren, fügt Fabric Apps es dem Schema automatisch hinzu.

  • Das id Feld ist bei Erstellungsvorgängen optional – der Server generiert eine UUID, wenn Sie es weglassen.
  • Sie können bei der Erstellung Ihre eigene UUID angeben, wenn Sie clientseitig generierte Bezeichner bevorzugen.
  • Zusammengesetzte Primärschlüssel und benutzerdefinierte Schlüsselnamen werden nicht unterstützt.
@entity()
export class Note {
  @uuid() id!: string;  // UUID primary key, auto-generated when omitted
  @text() title!: string;
  @text() content!: string;
}

Unterstützte Datentypen

Verwenden Sie diese Dekoratoren, um Feldtypen zu definieren:

Dekorateur Typ Description
@uuid() Schnur Feld für eindeutige Kennung.
@text() Schnur Textfeld mit optionalen Längeneinschränkungen.
@int() Zahl Ganzzahliges Feld.
@decimal() Zahl Dezimal- oder numerisches Feld.
@boolean() Boolescher Wert True- oder False-Feld.
@date() Date Datums- und Uhrzeitfeld, serialisiert aus ISO-Zeichenfolgen oder Date -Objekten.
@email() Schnur Textfeld mit E-Mail-Überprüfung.
@set() Schnur Aufzählung von String-Literalen.

Beispiel mit mehreren Typen

import { entity, uuid, text, int, decimal, boolean, date, set } from '@microsoft/rayfin-core';

@entity()
export class Product {
  @uuid() id!: string;
  @text() name!: string;
  @decimal() price!: number;
  @int() stockQuantity!: number;
  @boolean() isAvailable!: boolean;
  @date() createdAt!: Date;
  @set('draft', 'published', 'archived') status!: 'draft' | 'published' | 'archived';
}

Typmodifizierer

Fügen Sie Felddekoratoren Modifizierer hinzu, um Validierungen und Einschränkungen zu konfigurieren:

Modifizierer Description
{ optional: true } Lässt NULL-Werte zu. Felder sind standardmäßig erforderlich.
{ unique: true } Fügen Sie eine eindeutige Einschränkung hinzu.
{ default: value } Legen Sie einen Standardwertausdruck fest.
{ max: n }, { min: n } Zeichenfolgenlängeneinschränkungen (maximale und minimale Anzahl von Zeichen).
{ min: n }, { max: n } Einschränkungen für numerische Werte.

Hinweis

Die optionale TypeScript-Markierung (? nach einem Eigenschaftsnamen) wirkt sich nur auf den statischen TypeScript-Typ aus. Dadurch wird die Datenbankspalte nicht NULL-fähig. Um ein Feld als nullable zu kennzeichnen, fügen Sie { optional: true } zum Decorator hinzu. Wird ! verwendet, um zu bestätigen, dass ein erforderliches Feld vom Framework initialisiert wird.

Beispiel mit Modifizierern

@entity()
export class User {
  @uuid() id!: string;
  @email({ unique: true }) email!: string;
  @text({ min: 3, max: 50 }) username!: string;
  @text({ optional: true, max: 500 }) bio?: string;
  @int({ min: 0, max: 150 }) age!: number;
  @boolean({ default: false }) isVerified!: boolean;
}

Definieren von Beziehungen

Verwenden Sie die Dekoratoren @one() und @many(), um Navigationseigenschaften zwischen Entitäten zu definieren. Fabric Apps generiert automatisch Fremdschlüsselspalten, wenn Sie Beziehungen definieren.

  • 1:n – Wird für das Übergeordnete und @many() das Kind verwendet@one().
  • Viele-zu-eins – Verwenden Sie @one() für das untergeordnete Element, um auf das übergeordnete Element zu verweisen.
  • Viele-zu-viele-Beziehungen werden nicht unterstützt – verwenden Sie stattdessen eine explizite Verknüpfungsentität.

Beispiel für 1:n-Beziehung

import { entity, uuid, text, date, one, many } from '@microsoft/rayfin-core';

@entity()
export class Notebook {
  @uuid() id!: string;
  @text() name!: string;
  @date() createdAt!: Date;
  @many(() => Note) notes?: Note[];
}

@entity()
export class Note {
  @uuid() id!: string;
  @text() title!: string;
  @text() content!: string;
  @date() createdAt!: Date;
  @text() notebook_id!: string;
  @one(() => Notebook) notebook?: Notebook;
}

Wenn Sie @one(() => Notebook) für die Entität Note definieren, erstellt Fabric Apps automatisch eine notebook_id Fremdschlüsselspalte. Deklarieren Sie das Fremdschlüsselfeld explizit nur, wenn Sie beabsichtigen, es im Anwendungscode zu lesen oder festzulegen.

Benennungskonvention für Fremdschlüssel

Wenn Sie ein Fremdschlüsselfeld definieren, verwenden Sie die {property}_id Benennungskonvention:

@entity()
export class Note {
  @uuid() id!: string;
  @text() notebook_id!: string;      // Foreign key field
  @one(() => Notebook) notebook?: Notebook;  // Navigation property
}

Benutzerdefinierte Fremdschlüsselnamen (foreignKey, targetKey Optionen) werden nicht unterstützt.

Referenzsystementitäten

Fabric Apps unterstützt keine @one() Beziehungen, die auf Systementitäten verweisen, z. B. die integrierte USER-Entität. Um dem angemeldeten Benutzer eine Zeile zuzuordnen, fügen Sie ein einfaches user_id Feld vom Typ @text() hinzu und füllen Sie sie aus den Authentifizierungsansprüchen auf (in der Regel claims.sub):

@entity()
export class Task {
  @uuid() id!: string;
  @text() title!: string;
  @text() user_id!: string;  // System user ID from claims.sub
}

Filtern Sie Zeilen mithilfe von user_id in Ihren Rollenrichtlinien, um benutzerspezifischen Zugriff zu erzwingen.

Registrieren von Entitäten im Schema

Fügen Sie alle Entitätsklassen hinzu rayfin/data/schema.ts , damit der Client GraphQL-Proxys generieren kann:

import type { Note } from './Note.js';
import type { Notebook } from './Notebook.js';

export type NotesAppSchema = {
  Note: Note;
  Notebook: Notebook;
};

Aktualisieren Sie diesen Typ immer dann, wenn Sie eine neue Entität erstellen.

Schemaänderungen anwenden

Wenden Sie nach dem Definieren oder Ändern von Entitäten die Änderungen auf die Datenbank an:

  1. Stellen Sie das aktualisierte Schema für Fabric bereit:

    npx rayfin up db apply
    
  2. Wenn die Schemaänderung destruktive Vorgänge (Ablegen von Spalten, Umbenennen von Tabellen) enthält, warnt Sie die CLI und lehnt den Vorgang ab. Verwenden Sie --force diese Option, um die Sicherheitsüberprüfung außer Kraft zu setzen:

    npx rayfin up db apply --force
    

Hinweis

Die Verwendung --force kann zu Datenverlust führen. Überprüfen Sie die aufgelisteten Vorgänge sorgfältig, bevor Sie fortfahren.

Bewährte Methoden

  • Definieren Sie Fremdschlüsselfelder nur, wenn Sie sie im Code lesen oder setzen müssen – Fabric Apps generiert sie automatisch aus Navigations-Decorators.
  • Verwenden Sie relative Importe mit .js Erweiterungen in Entitätsdateien, damit das ausgegebene ESM-JavaScript ordnungsgemäß aufgelöst wird.
  • Informationen zu Autorisierungsmustern und rollenbasiertem Zugriff finden Sie unter Definieren von Datenberechtigungen.

Troubleshooting

Fehlende Beziehungen

Wenn Beziehungen nicht in der API angezeigt werden, überprüfen Sie Folgendes:

  • Der Navigationsdekorator (@one() oder @many()) ist vorhanden.
  • Die Entität ist registriert in rayfin/data/schema.ts.