Define a Realm Object Schema - .NET SDK
On this page
- Define a Relationship Property
- Many-to-One
- Many-to-Many
- Inverse Relationships
- Define an Embedded Object Property
- Custom Setters
- Property Annotations
- Primary Key
- Required and Optional Properties
- Default Field Values
- Index a Property
- Ignore a Property
- Rename a Property
- Rename a Class
- Omit Classes from your Realm Schema
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.
Define a Relationship Property
If you're using Realm Sync, you can also define your relationships in the App Services UI.
Realm Database supports several kinds of object relationships.
Many-to-One
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.
Many-to-Many
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; } }
Inverse Relationships
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. [ ] 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. [ ] 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.
Define an Embedded Object Property
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 { [ ] [ ] 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.
Custom Setters
Realm will not store a property with a custom setter. To use a custom setter,
store the property value in a private property and then
map that value to a public property with the custom setter. Realm will store the
private property, while you modify its value via the public property.
In the following code, the private email
property is stored in the realm,
but the public Email
property, which provides validation, is not persisted:
// This property will be stored in the Realm private string email { get; set; } // Custom validation of the email property. // This property is *not* stored in Realm. public string Email { get { return email; } set { if (!value.Contains("@")) throw new Exception("Invalid email address"); email = value; } }
Property Annotations
Use annotations to customize your Realm object models.
Primary Key
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 { [ ] public string Name { get; set; } public int Age { get; set; } public Person Owner { get; set; } }
Required and Optional Properties
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 { [ ] public string Name { get; set; } public IList<Dog> Dogs { get; } }
Default Field Values
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"; }
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.
Index a Property
To index a property, use the [Indexed] attribute:
public class Person : RealmObject { [ ] public string Name { get; set; } public IList<Dog> Dogs { get; } }
Ignore a Property
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:
// Rather than store an Image in Realm, // store the path to the Image... public string ThumbnailPath { get; set; } // ...and the Image itself can be // in-memory when the app is running: [ ]public Image Thumbnail { get; set; }
Rename a Property
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 { [ ] public string Name { get; set; } }
Rename a Class
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:
[ ]public class Person : RealmObject { public string Name { get; set; } }
Omit Classes from your Realm Schema
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.Schema = new[] { typeof(LoneClass) }; // Or, specify multiple classes to use in the Realm config.Schema = new[] { typeof(Dog), typeof(Cat) }; } }