Docs Menu
Docs Home
/ /
Datos del modelo

Modelos de Objetos - .NET SDK

Las clases de Realm son clases C# regulares que definen el esquema de Realm.

Importante

Herencia

Todos los objetos de Realm heredan del Interfaz IRealmObject, IEmbeddedObject o IAsymmetricObject y debe declararse partial clases.

En versiones del SDK de .NET anteriores 10.18.0 a, los objetos derivan de las clases base RealmObject, EmbeddedObject o AsymmetricObject. Este enfoque para la definición del modelo Realm aún se admite, pero no incluye nuevas funciones como las anotaciones de nulabilidad. En una futura versión del SDK, las clases base quedarán obsoletas. Debe usar las interfaces para cualquier clase nueva que escriba y considerar la migración de las clases existentes.

Nota

Los nombres de clase están limitados a un máximo de 57 caracteres UTF-8.

Un esquema de objeto es un objeto de configuración que define las propiedades y relaciones de un objeto de Realm. Las aplicaciones cliente de Realm definen esquemas de objeto con la implementación de la clase nativa en su lenguaje correspondiente mediante el esquema de objeto.

Los esquemas de objeto especifican restricciones sobre las propiedades de los objetos, como el tipo de dato de cada propiedad y si una propiedad es obligatoria o no. Los esquemas también pueden definir relaciones entre los tipos de objetos de un dominio.

Cada aplicación tiene un esquema de App Services, compuesto por una lista de esquemas de objetos para cada tipo de objeto que los dominios de esa aplicación pueden contener. Realm garantiza que todos los objetos de un dominio se ajusten al esquema para su tipo de objeto y valida los objetos cada vez que se crean, modifican o eliminan.

Las propiedades del esquema son propiedades estándar de C# en un RealmObject. Existen varias anotaciones de la propiedad que puedes usar para definir con mayor precisión cómo un Realm gestiona una propiedad específica.

Una clave principal es una propiedad que identifica de forma única a un objeto. Puede crear una clave principal con cualquiera de los siguientes tipos (o sus equivalentes que aceptan valores NULL):

  • ObjectId

  • UUID

  • string

  • char

  • byte

  • short

  • int

  • long

Puede definir una clave principal en una sola propiedad para un tipo de objeto como parte del esquema del objeto. Realm indexa automáticamente las propiedades de clave principal, lo que permite leer y modificar objetos eficientemente según su clave principal.

Si un tipo de objeto tiene una clave principal, entonces todos los objetos de ese tipo deben incluir la propiedad de clave principal con un valor que sea único entre los objetos del mismo tipo en un ámbito.

Nota

Una vez que asigna una propiedad como clave principal, no puede cambiarla.

El siguiente ejemplo demuestra cómo designar una clave principal en un esquema de objeto:

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

Tip

Los índices mejoran significativamente los tiempos de consulta en un dominio. Sin índices, Realm escanea todos los documentos de una colección para seleccionar los que coinciden con la consulta. Sin embargo, si existe un índice aplicable para una consulta, Realm lo utiliza para limitar el número de documentos que debe inspeccionar.

Puede indexar propiedades con los siguientes tipos:

  • bool

  • byte

  • short

  • int

  • long

  • DateTimeOffset

  • char

  • string

  • ObjectId

  • UUID

Nota

Añadir un índice acelera las consultas, pero reduce ligeramente los tiempos de escritura y aumenta la sobrecarga de almacenamiento y memoria. Los índices requieren espacio en el archivo de dominio, por lo que añadir un índice a una propiedad aumenta el espacio en disco que consume dicho archivo. Cada entrada de índice tiene un mínimo de 12 bytes.

Para indexar una propiedad, utilice el atributo Indexed. Con el Indexed atributo, puede especificar el tipo de índice de la propiedad mediante la enumeración IndexType. En el siguiente ejemplo, tenemos un índice predeterminado ("General") en la Name propiedad:

public partial class Person : IRealmObject
{
[Indexed(IndexType.General)]
public string Name { get; set; }
[Indexed(IndexType.FullText)]
public string Biography { get; set; }
}

Nota

Cuando se crea un índice, este se crea en el realm local y no en una colección de Atlas. Si se necesita realizar queries directamente en una colección de Atlas y se desea mejorar el rendimiento, consulte Crear, ver, descartar y ocultar índices.

Además de los índices estándar, Realm también admite índices de texto completo (FTS) en string propiedades. Aunque es posible query un campo de string con o sin un índice estándar, un índice FTS permite buscar varias palabras y frases y excluir otras.

Para obtener más información sobre cómo consultar índices de texto completo, consulta Búsqueda de texto completo (LINQ) y Búsqueda de texto completo (RQL).

Para indexar una propiedad FTS, utilice el atributo Indexed con la enumeración IndexType.FullText. En el siguiente ejemplo, tenemos un FullText índice en la Biography propiedad:

public partial class Person : IRealmObject
{
[Indexed(IndexType.General)]
public string Name { get; set; }
[Indexed(IndexType.FullText)]
public string Biography { get; set; }
}

Puede usar las funciones integradas del lenguaje para asignar un valor predeterminado a una propiedad. En C#, puede asignar un valor predeterminado a las primitivas en la declaración de la propiedad. No puede establecer un valor predeterminado en una colección, excepto para establecerlo en null!. Incluso si establece una colección en null!, las colecciones siempre se inicializan en el primer acceso, por lo que nunca serán nulas.

public partial class Person : IRealmObject
{
public string Name { get; set; } = "foo";
public IList<PhoneNumber> PhoneNumbers { get; } = null!;
}

Nota

Valores predeterminados y nulabilidad

Aunque los valores predeterminados aseguran que un objeto recién creado no pueda contener un valor de null (a menos que se especifique un valor predeterminado de null), no afectan la posibilidad de nulidad de una propiedad. Para hacer que una propiedad no sea anulable, consulta Propiedades requeridas.

Si no desea guardar una propiedad de su modelo en un dominio, puede ignorarla. Una propiedad se ignora por defecto si no se implementa automáticamente o no tiene un definidor.

Ignorar una propiedad de un modelo de objeto Realm con el atributo Ignorado:

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

De forma predeterminada, Realm usa el nombre definido en la clase del modelo para representar las propiedades internamente. En algunos casos, podría ser conveniente cambiar este comportamiento:

  • Para facilitar el trabajo en diferentes plataformas, ya que las convenciones de nomenclatura difieren.

  • Para cambiar un nombre de propiedad en .NET sin forzar una migración.

Elegir un nombre interno diferente del nombre utilizado en las clases del modelo tiene las siguientes implicaciones:

  • Las migraciones deben utilizar el nombre interno al crear clases y propiedades.

  • Los errores de esquema informados utilizarán el nombre interno.

Utilice el atributo [MapTo] para cambiar el nombre de una propiedad:

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

De forma predeterminada, Realm usa el nombre definido en la clase del modelo para representar las clases internamente. En algunos casos, podría ser conveniente cambiar este comportamiento:

  • Para admitir múltiples clases de modelo con el mismo nombre simple en diferentes espacios de nombres.

  • Para facilitar el trabajo en diferentes plataformas, ya que las convenciones de nomenclatura difieren.

  • Para utilizar un nombre de clase que sea más largo que el límite de caracteres 57 impuesto por Realm.

  • Para cambiar un nombre de clase en .NET sin forzar una migración.

Utilice el atributo [MapTo] para cambiar el nombre de una clase:

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

Realm no almacenará una propiedad con un establecedor personalizado. Para usar un establecedor personalizado, almacene el valor de la propiedad en una propiedad privada y luego asigne ese valor a una propiedad pública con el establecedor personalizado. Realm almacenará la propiedad privada, mientras que usted modificará su valor mediante la propiedad pública. En el siguiente código, la propiedad privada email se almacena en el dominio, pero la propiedad pública Email, que proporciona validación, no se conserva:

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

Nuevo en la versión 12.2.0.

A partir de la versión del SDK,12.2.0 se pueden almacenar colecciones de datos mixtos dentro de una RealmValue propiedad. Esta función permite modelar estructuras de datos complejas, como documentos JSON o MongoDB, sin necesidad de definir un modelo de datos estricto.

Los datos no estructurados son aquellos que no se ajustan fácilmente a un esquema esperado, lo que dificulta o hace poco práctico modelarlos para clases de datos individuales. Por ejemplo, su aplicación podría tener datos muy variables o dinámicos cuya estructura se desconoce en tiempo de ejecución.

Almacenar colecciones en una propiedad mixta ofrece flexibilidad sin sacrificar la funcionalidad, incluyendo una sincronización eficiente al usar Device Sync. Además, puede trabajar con ellas de la misma manera que con una colección no mixta:

  • Puedes anidar colecciones mixtas hasta 100 niveles.

  • Puede consultar y reaccionar ante los cambios en colecciones mixtas.

  • Puede buscar y actualizar elementos de colección mixtos individuales.

Sin embargo, almacenar datos en colecciones mixtas tiene menos rendimiento que usar un esquema estructurado o serializar blobs JSON en una única propiedad de cadena.

Para modelar datos no estructurados en su aplicación, defina las propiedades adecuadas en su esquema como tipos RealmValue. A continuación, puede configurar estas RealmValue propiedades como una lista o un diccionario de RealmValue elementos. Tenga en cuenta que RealmValue no puede representar un conjunto ni un objeto incrustado.

Tip

  • Utilice un mapa de tipos de datos mixtos cuando el tipo sea desconocido pero cada valor tendrá un identificador único.

  • Utilice una lista de tipos de datos mixtos cuando el tipo sea desconocido, pero el orden de los objetos sea importante.

De forma predeterminada, el esquema de dominio de su aplicación incluye todas las clases que implementan IRealmObject o IEmbeddedObject. Si solo desea incluir un subconjunto de estas clases en su esquema de dominio, puede actualizar su configuración para incluir las clases específicas que desee:

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

En C#, los tipos de valor, como int booly, no admiten valores nulos de forma implícita. Sin embargo, pueden hacerse opcionales mediante la notación de signo de? interrogación ().

A partir de C# 8.0, se introdujeron los tipos de referencia que aceptan valores NULL. Si su proyecto utiliza C# 8.0 o posterior, también puede declarar tipos de referencia, como string y byte[], como que aceptan valores NULL con ?.

Nota

A partir de .NET,6.0 el contexto que acepta valores NULL está habilitado de forma predeterminada para los proyectos nuevos. Para proyectos más antiguos, puede habilitarlo manualmente. Para obtener más información, consulte https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/nullable-reference-types#setting-the-nullable-context.

El SDK de Realm .NET es totalmente compatible con el contexto que admite valores nulos y utiliza la nulabilidad para determinar si una propiedad es obligatoria u opcional. El SDK tiene las siguientes reglas:

  • Realm asume que tanto las propiedades de valor como las de referencia son obligatorias si no se designan como nulas. Si se designan como nulas mediante ?, Realm las considera opcionales.

  • Debes declarar las propiedades que son tipos de objetos Realm como anulables.

  • No se pueden declarar colecciones (listas, conjuntos, vínculos de retroceso y diccionarios) como anulables, pero sus parámetros pueden ser anulables de acuerdo con las siguientes reglas:

    • Para todos los tipos de colecciones, si los parámetros son primitivos (tipos de valor o de referencia), pueden ser obligatorios o anulables.

    • Para listas, conjuntos y vínculos de retroceso, si los parámetros son objetos Realm,no pueden aceptar valores nulos.

    • Para los diccionarios con un tipo de valor de objeto Realm,debe declarar el parámetro de tipo de valor como anulable.

El siguiente fragmento de código demuestra estas reglas:

#nullable enable
public partial class Person : IRealmObject
{
/* Reference Types */
public string NonNullableName { get; set; }
public string? NullableName { get; set; }
public byte[] NonNullableArray { get; set; }
public byte[]? NullableArray { get; set; }
/* Value Types */
public int NonNullableInt { get; set; }
public int? NullableInt { get; set; }
/* Realm Objects */
public Dog? NullableDog { get; set; }
// public Dog NonNullableDog { get; set; } // Compile-time error
/* Collections of Primitives */
public IList<int> IntListWithNonNullableValues { get; }
public IList<int?> IntListWithNullableValues { get; }
// public IList<int>? NullableListOfInts { get; } // Compile-time error
/* Collections of Realm Objects */
public IList<Dog> ListOfNonNullableObjects { get; }
// public IList<Dog>? NullableListOfObjects { get; } // Compile-time error
// public IList<Dog?> ListOfNullableObjects { get; } // Compile-time error
public ISet<Dog> SetOfNonNullableObjects { get; }
// public ISet<Dog>? NullableSetOfObjects { get; } // Compile-time error
// public ISet<Dog?> SetOfNullableObjects { get; } // Compile-time error
public IDictionary<string, Dog?> DictionaryOfNullableObjects { get; }
// public IDictionary<string, Dog> DictionaryOfNonNullableObjects { get; } // Compile-time error
// public IDictionary<string, Dog>? NullableDictionaryOfObjects { get; } // Compile-time error
[Backlink(nameof(Dog.Person))]
public IQueryable<Dog> MyDogs { get; }
// [Backlink(nameof(Dog.People))]
// public IQueryable<Dog?> MyDogs { get; } // Compile-time error
}

Nota

Si está utilizando la definición de tipo de esquema anterior (sus clases derivan de la RealmObject clase base) o no tiene habilitada la nulabilidad, deberá utilizar el atributo [Required] para string cualquier byte[] propiedad y requerida.

Quizás prefiera tener más flexibilidad al definir la nulidad de las propiedades en sus objetos Realm. Puede hacerlo configurando realm.ignore_objects_nullability = true en un archivo de configuración global.

Si habilita realm.ignore_objects_nullability, las anotaciones de nulidad se ignorarán en las propiedades de objetos Realm, incluidas las colecciones de objetos Realm.

Volver

Datos del modelo

En esta página