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 exactlyT's namespace, fromT's assembly. It skips enums, static classes and anything marked[Exclude].Add<T>also adds every typeTreferences, unless you passincludeAllReferencedModels: false.AddAssemblytakes 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.