Docs Menu

Docs HomeRealm

Object Models - .NET SDK

On this page

  • Create an Object Model
  • Object Schema
  • Property Annotations
  • Primary Key
  • Indexes
  • Required and Optional Properties
  • Default Field Values
  • Ignore a Property
  • Rename a Property
  • Rename a Class
  • Custom Setters
  • Omit Classes from your Realm Schema
  • Data Binding and MVVM

Realm classes are regular C# classes that define the Realm schema.

Important

Inheritance

All Realm objects inherit from the IRealmObject, IEmbeddedObject, or IAsymmetricObject interface and should be declared partial classes.

You can also derive from the RealmObject, EmbeddedObject, or AsymmetricObject base classes. However, in the future we may deprecate the base classes. You should use the interfaces for any new classes that you write.

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 Object Schema.

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 App has a App Services Schema composed of a list of object schemas for each type of object that the realms in that application may contain. 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.

Schema properties are standard C# properties on a RealmObject. There are several property annotations that you can use to more finely define how a Realm handles a specific property.

A primary key is a property that uniquely identifies an object. You can create a primary key with any of the following types (or their nullable counterparts):

  • ObjectId

  • UUID

  • string

  • char

  • byte

  • short

  • int

  • long

You may define a primary key on a single property for an object type as part of the object schema. Realm Database automatically indexes primary key properties, which allows you to efficiently read and modify objects based on their primary key.

If an object type has a primary key, then all objects of that type must include the primary key property with a value that is unique among objects of the same type in a realm.

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 partial class Dog : IRealmObject
{
[PrimaryKey]
public string Name { get; set; }
public int Age { get; set; }
public Person Owner { get; set; }
}

Tip

Indexes support the efficient execution of queries in Realm Database. Without indexes, Realm Database must perform a collection scan, i.e. scan every document in a collection, to select those documents that match a query. If an appropriate index exists for a query, Realm Database can use the index to limit the number of documents that it must inspect.

Indexes are special data structures that store a small portion of a realm's data in an easy to traverse form. The index stores the value of a specific property ordered by the value of the property. The ordering of the index entries supports efficient equality matches and range-based query operations.

Adding an index can speed up some queries at the cost of slightly slower write times and additional storage and memory overhead. Indexes require space in your realm file, so adding an index to a property will increase disk space consumed by your realm file. Each index entry is a minimum of 12 bytes.

You can index properties with the following types:

  • bool

  • byte

  • short

  • int

  • long

  • DateTimeOffset

  • char

  • string

  • ObjectId

  • UUID

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

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

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 IRealmObject or IEmbeddedObject 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 partial class Person : IRealmObject
{
[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 partial class Person : IRealmObject
{
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.

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:
[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 partial class Person : IRealmObject
{
[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 partial class Person : IRealmObject
{
public string Name { get; set; }
}

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;
}
}

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

// Declare your schema
partial class LoneClass : IRealmObject
{
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) };
}
}

When building a MAUI/Xamarin app using the MVVM pattern, you often want proper data binding in both directions between the View and ViewModel: if a property value changes in the UI, the ViewModel should be notified, and vice-versa. ViewModels typically implement the INotifyPropertyChange interface to ensure this.

However, when you bind UI elements to a RealmObject, this notification happens automatically, thus greatly simplifying your ViewModel code.

You can also bind a UI element to a realm Live Query. For example, if you bind a ListView to a live query, then the list will update automatically when the results of the query change; you do not need to implement the INotifyPropertyChange interface.

For example, if you bind a ListView to a query that returns all Product objects, the list of available products updates automatically when a product is added, changed, or removed from the realm:

// Somewhere in your ViewModel
AllProducts = realm.All<Products>();
<!-- Somewhere in your View -->
<ListView ItemsSource="{Binding AllProducts}">
←  Model Data - .NET SDKObject Models & Schemas - .NET SDK →
Share Feedback
© 2023 MongoDB, Inc.

About

  • Careers
  • Investor Relations
  • Legal Notices
  • Privacy Notices
  • Security Information
  • Trust Center
© 2023 MongoDB, Inc.