Relatude Help

Two ways to register a datamodel

Register model types in code with OnDatamodelInit, or as datamodel sources in relatude.db.json. The two add up: the server loads the sources first, then runs OnDatamodelInit on the same Datamodel.

In Program.cs, the usual choice when the model ships with the application. It is refactor-safe, and a mistake fails at compile time:

options.OnDatamodelInit = (dm, database) => {
    dm.AddNamespace<IVenue>();       // every node and relation type in IVenue's namespace
    dm.Add<IEvent>();                // one type, and the types it references (not embedded ones)
    dm.Add(typeof(IAttendee));
    dm.AddAssembly(typeof(IVenue).Assembly, "VenueApp.Models.*");   // a namespace pattern
};
  • AddNamespace<T> adds the types in exactly T's namespace, from T's assembly. It skips enums, static classes and anything marked [Exclude].
  • Add<T> also adds every type T references, unless you pass includeAllReferencedModels: false.
  • AddAssembly takes one namespace, or a pattern in which * stands for any run of characters.

With more than one database, branch on the database the callback is given:

options.OnDatamodelInit = (dm, database) => {
    if (database.Name == "Catalog") dm.AddNamespace<IProduct>();
    else dm.AddNamespace<IAuditEntry>();
};

In relatude.db.json, when the model must change without a rebuild, or differs between deployments of the same build. You can also edit the sources in the admin UI, on the database's Settings → Data model → Model sources.

"DatamodelSources": [
  {
    "Id": "8a3f…",                     // required, unique among the sources
    "Name": "VenueApp",
    "Type": "CompiledTypes",
    "Reference": "VenueApp",           // the assembly; empty means the application itself
    "Namespace": "VenueApp.Models.*"   // required: one namespace, or a pattern
  }
]

There are two kinds of source:

Type What it loads
CompiledTypes Types compiled into the application: every type in Namespace in the assembly Reference names.
RuntimeTypes Model files read from disk when the database opens: datamodel JSON, as the model editor writes it. The model can change without a rebuild.

Code is reserved. It marks the types added from code, and configuring it as a source throws.

Key What it is
Id Required and unique. Every type is tagged with its source's id, which tells the admin UI where a type came from and whether it may edit it.
Name A label for the admin UI and error messages.
Type CompiledTypes or RuntimeTypes.
Reference CompiledTypes: the assembly name, without .dll. Empty is the entry assembly, the application itself.
Namespace CompiledTypes, required: one namespace or a pattern. VenueApp.Models.* takes VenueApp.Models and every namespace under it; VenueApp.*.Models takes VenueApp.Web.Models and VenueApp.Api.Models.
Filepath RuntimeTypes: a .json file, or a folder searched recursively. Empty is a folder of the source's own, relatude.data/modelsources/{Name}.
FileIO RuntimeTypes: the id of a storage provider to read the model from instead of disk, for a model kept in blob storage. Reference then names the file.
SourceCodePath CompiledTypes: the folder of the model's C# files, for the model editor.
GenerateModelFile CompiledTypes: the model editor owns SourceCodePath and generates its files. Default false.
Enabled false leaves the source out of the model. Default true.
Color The CSS colour the admin UI marks the source's types with. Empty picks one.

Relative paths resolve against the root data folder.

Every configured source must load. A source that throws stops the database from opening, so a source added in the admin UI starts with Enabled off: fill it in, then turn it on. While a source is off, nodes of its types read without the properties those types declare. A source with no types yet (an empty folder, a namespace with no model types) loads empty and leaves a note in the log, where a typo shows up.

A RuntimeTypes type uses your class when you have one: a plain class with the type's full name. Without one, the server generates a class when the database opens. The type then works by name (db.Create("Venue"), untyped queries, the admin UI), but compiled code cannot refer to it. A source without a Filepath reads from a folder named after the source, so rename that folder too if you rename the source by hand.

The model editor and CompiledTypes. The model editor writes to a compiled source only when GenerateModelFile is on and SourceCodePath names a folder inside the project that builds the assembly. After a change, rebuild and restart. The folder belongs to the editor: activating a model deletes every file in it and generates one file per node type and relation, each marked // <auto-generated>. It lists the files without that mark first and asks before deleting them, so point SourceCodePath at a folder of its own, not at the project root.

Node-typed properties without a relation become Reference or References properties (chapter 8). To make them relations instead, set the static DatamodelSource.AutoDeduceRelations = true before the database opens (for sources in relatude.db.json), or pass autoDeduceRelations: true to Add, AddNamespace or AddAssembly.