Navigation

Define a Realm Object Schema - .NET SDK

An object schema is a configuration object that defines the properties and relationships of a Realm object. Realm client applications define object schemas with the native class implementation in their respective language using the Realm Object Model.

Object schemas specify constraints on object properties such as the data type of each property and whether or not a property is required. Schemas can also define relationships between object types in a realm.

Every Realm app has a Realm Schema composed of a list of object schemas for each type of object that the realms in that application may contain. MongoDB Realm guarantees that all objects in a realm conform to the schema for their object type and validates objects whenever they're created, modified, or deleted.

Realm Database supports several kinds of object relationships.

Tip
See also:

To set up a many-to-one or one-to-one relationship, create a property in your application whose type inherits RealmObject or EmbeddedObject:

public class Dog : RealmObject
{
// ... other property declarations
public Person Owner { get; set; }
}
public class Person : RealmObject
{
// ... other property declarations
public string Name { get; set; }
}

Each Dog references zero or one Person instances. Nothing prevents multiple Dog instances from referencing the same Person as an owner; the distinction between a many-to-one and a one-to-one relationship is up to your application.

Setting a relationship property to null removes the connection between objects, but Realm Database does not delete the referenced object unless that object is embedded.

You can create a relationship between one object and any number of objects using a property of type IList<T> in your application, where T is a subclass of RealmObject or EmbeddedObject:

public class Dog : RealmObject
{
// ... other property declarations
public string Name { get; set; }
}
public class Person : RealmObject
{
// ... other property declarations
public IList<Dog> Dogs { get; }
}

By default, Realm Database relationships are unidirectional. You can follow a link from one class to a referenced class, but not in the opposite direction. You can provide a link in the opposite direction with the [Backlink] attribute:

class Dog : RealmObject
{
// To-one relationship from the Dog to its owner
public Person Owner { get; set; }
}
class Person : RealmObject
{
// An inverse relationship that returns all Dog instances that have Dog.Owner set to
// the current Person.
[Backlink(nameof(Dog.Owner))]
public IQueryable<Dog> Dogs { get; }
// To-many relationship, containing a collection of all hobbies the current person enjoys
public IList<Hobby> Hobbies { get; }
}
class Hobby : RealmObject
{
// An inverse relationship that returns all Person instances that have the current Hobby
// instance in their Hobbies list.
[Backlink(nameof(Person.Hobbies))]
public IQueryable<Person> PeopleWithThatHobby { get; }
}

Since relationships are many-to-one or many-to-many, following inverse relationships can result in zero, one, or many objects.

Like any other RealmResults set, you can query an inverse relationship.

Realm Database provides the ability to nest objects within other objects. This has several advantages:

  • If using Realm Sync, objects will translate into MongoDB documents that follow a denormalized data model.
  • When you delete an object that contains another object, the delete operation removes both objects from the realm, so unused objects don't accumulate in your realm file, taking up valuable space on user's mobile devices.

To embed an object, extend EmbeddedObject for the class that you'd like to nest within another class:

public class Address : EmbeddedObject
{
public ObjectId Id { get; set; }
public string Street { get; set; }
public string City { get; set; }
}
public class Contact : RealmObject
{
[PrimaryKey]
[MapTo("_id")]
public ObjectId Id { get; set; }
public string Name { get; set; }
public Address Address { get; set; } // embed a single address
}

Then, any time you reference that class from another class, Realm Database will embed the referenced class within the enclosing class.

Use annotations to customize your Realm object models.

Note

Once you assign a property as a primary key, you cannot change it.

The following example demonstrates how to designate a primary key in an object schema:

public class Dog : RealmObject
{
[PrimaryKey]
public string Name { get; set; }
public int Age { get; set; }
public Person Owner { get; set; }
}

In C#, value types are implicitly non-nullable, but can be made optional by appending ?. Reference types, such as string and byte[], are implicitly nullable and can be made required by annotating them with the [Required] attribute. Properties of types that inherit from RealmObject or EmbeddedObject are special and can always be null. Applying [Required] on such a property will result in a compilation error.

You can use the [Required] attribute as seen in the following example:

public class Person : RealmObject
{
[Required]
public string Name { get; set; }
public IList<Dog> Dogs { get; }
}

You can use the built-in language features to assign a default value to a property. In C#, you can assign a default value in the property declaration.

public class Person : RealmObject
{
public string Name { get; set; } = "foo";
}
Note
Default Values and Nullability

While default values ensure that a newly created object cannot contain a value of null (unless you specify a default value of null), they do not impact the nullability of a property. To make a property non-nullable, see Required Properties.

To index a property, use the [Indexed] attribute:

public class Person : RealmObject
{
[Indexed]
public string Name { get; set; }
public IList<Dog> Dogs { get; }
}

If you don't want to save a property in your model to a realm, you can ignore that property. A property is ignored by default if it is not autoimplemented or does not have a setter.

Ignore a property from a Realm object model with the [Ignored] attribute:

[Ignored]
public Image Thumbnail { get; set; }

By default, Realm Database uses the name defined in the model class to represent properties internally. In some cases you might want to change this behavior:

  • To make it easier to work across platforms, since naming conventions differ.
  • To change a property name in .NET without forcing a migration.

Choosing an internal name that differs from the name used in model classes has the following implications:

  • Migrations must use the internal name when creating classes and properties.
  • Schema errors reported will use the internal name.

Use the [MapTo] attribute to rename a property:

public class Person : RealmObject
{
[MapTo("moniker")]
public string Name { get; set; }
}

By default, Realm Database uses the name defined in the model class to represent classes internally. In some cases you might want to change this behavior:

  • To support multiple model classes with the same simple name in different namespaces.
  • To make it easier to work across platforms, since naming conventions differ.
  • To use a class name that is longer than the 57 character limit enforced by Realm Database.
  • To change a class name in .NET without forcing a migration.

Use the [MapTo] attribute to rename a class:

[MapTo("Human")]
public class Person : RealmObject
{
public string Name { get; set; }
}

By default, your application's Realm Schema includes all classes that inherit from RealmObject or EmbeddedObject. If you only want to include a a subset of these classes in your Realm Schema, you can update your configuration to include the specific classes you want:

// Declare your schema
class LoneClass : RealmObject
{
public string Name { get; set; }
}
class AnotherClass
{
private void SetUpMyRealmConfig()
{
// Define your config with a single class
var config = new RealmConfiguration("RealmWithOneClass.realm");
config.ObjectClasses = new[] { typeof(LoneClass) };
// Or, specify multiple classes to use in the Realm
config.ObjectClasses = new[] { typeof(DogA), typeof(Cat) };
}
}
Give Feedback