Docs Menu
Docs Home
/ /
Datos del modelo

Relaciones - SDK de Kotlin

Esta página describe cómo definir relaciones entre objetos en su modelo de datos. Para obtener más información sobre los objetos Realm y cómo definirlos, consulte Definir un modelo de objetos Realm - SDK de Kotlin.

A diferencia de una base de datos relacional, Realm no utiliza tablas puente ni uniones explícitas para definir relaciones. En su lugar, gestiona las relaciones mediante objetos incrustados o propiedades de referencia a otros objetos de Realm. Se leen y escriben directamente en estas propiedades. Esto permite que las consultas sobre relaciones sean tan eficientes como las consultas sobre cualquier otra propiedad.

Existen dos tipos principales de relaciones entre objetos de Realm:

  • Relación de uno a uno

  • Relación de muchos

El dominio no limita inherentemente las referencias a objetos de otros objetos dentro del mismo dominio. Esto significa que las relaciones de dominio son implícitamente "muchos a uno" o "muchos a muchos". La única manera de restringir una relación a "uno a uno/uno a muchos" en lugar de "muchos a uno/muchos a muchos" es usar un objeto incrustado, que es un objeto anidado con solo un padre.

Puede definir relaciones en su esquema de objetos definiendo una propiedad de objeto que haga referencia a otro objeto Realm. Obtenga más información sobre el uso de objetos Realm como propiedades.

Puede definir relaciones utilizando los siguientes tipos:

  • RealmObject

  • RealmList <? extends RealmObject>

  • RealmSet <? extends RealmObject>

También puede incrustar un objeto Realm directamente dentro de otro para crear una estructura de datos anidada con un tipo EmbeddedRealmObject. Sin embargo, los objetos incrustados tienen restricciones adicionales. Consulte la Consulte la sección Defina una sección de objeto incrustado para obtener más información.

Una relación uno a uno asigna una propiedad a una sola instancia de un RealmObject tipo de objeto. Nada impide que varias instancias de un objeto principal hagan referencia a la misma instancia secundaria. Si desea aplicar una relación uno a uno estricta, utilice un objeto incrustado.

Nota

Al establecer un campo de relación a uno como null, se elimina la conexión entre los objetos, pero Realm no elimina el objeto referenciado. Si desea eliminar el objeto referenciado al eliminar el objeto principal, utilice un objeto incrustado.

Para definir una relación de uno a uno entre objetos, defina una propiedad de objeto opcional cuyo tipo sea un objeto RealmObject definido en su modelo de datos. Puede ser un tipo de objeto de Realm diferente o el mismo tipo de objeto de Realm:

// Relationships of Realm objects must be of RealmObject type
class Frog : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var name: String = ""
var age: Int = 0
// Property of RealmObject type (MUST be null)
var favoritePond: Pond? = null
var bestFriend: Frog? = null
}

Una relación de uno a muchos asigna una propiedad a cero o más instancias de un RealmObject tipo de objeto. Nada impide que varias instancias de un objeto padre hagan referencia a la misma instancia hija. Si desea aplicar una relación estricta de uno a muchos, utilice un objeto incrustado.

En Realm, las relaciones de varios elementos son colecciones (una RealmList o un RealmSet) de objetos de Realm. Para obtener más información sobre cómo definir colecciones en el modelo de objetos, consulte Definir propiedades de colección.

Para definir una relación de varios objetos, defina una propiedad de objeto cuyo tipo sea RealmList<E> o RealmSet<E>, donde <E> es un tipo de objeto RealmObject definido en su modelo de datos. Este puede ser un tipo de objeto de Realm diferente o el mismo tipo de objeto de Realm:

// Relationships of RealmList<E> or RealmSet<E> must be of RealmObject type
class Forest : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var name: String = ""
// Set of RealmObject type (CANNOT be null)
var frogsThatLiveHere: RealmSet<Frog> = realmSetOf()
// List of RealmObject type (CANNOT be null)
var nearbyPonds: RealmList<Pond> = realmListOf()
}

Una relación inversa es una relación de retroenlace automático entre un RealmObject objeto secundario y cualquier otro objeto principal que haga referencia a él. Las relaciones inversas pueden vincularse con objetos secundarios en una relación de varios a uno o de varios a varios. Si desea aplicar una relación inversa estricta de uno a uno o de uno a varios, utilice un objeto incrustado.

Las definiciones de relación son unidireccionales, por lo que debe definir explícitamente una propiedad en el modelo del objeto como una relación inversa. Por ejemplo, la relación a muchos "El usuario tiene muchas publicaciones" no crea automáticamente la relación inversa "La publicación pertenece al usuario". Sin embargo, puede agregar una propiedad de usuario a la publicación que apunte a su propietario. Esto le permite consultar la relación inversa de la publicación al usuario en lugar de ejecutar una consulta independiente para buscar al usuario al que pertenece la publicación. Dado que las relaciones son de muchos a uno o de muchos a muchos, las siguientes relaciones inversas pueden generar cero, uno o muchos objetos.

Nota

Realm actualiza automáticamente las relaciones implícitas al añadir o eliminar un objeto de la relación especificada. No es posible añadir ni eliminar elementos manualmente de una colección de backlinks.

Para definir una relación inversa entre objetos, primero defina una propiedad de colección en el objeto principal cuyo tipo sea RealmList<E>, RealmSet<E> o RealmDictionary<E>, donde <E> es un tipo de objeto RealmObject definido en su modelo de datos. Este puede ser un tipo de objeto Realm diferente o el mismo tipo de objeto Realm:

// Parent object must have RealmList<E>, RealmSet<E>, or
// RealmDictionary<K,V> property of child type
class User : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var name: String = ""
// List of child RealmObject type (CANNOT be nullable)
var posts: RealmList<Post> = realmListOf()
// Set of child RealmObject type (CANNOT be nullable)
var favoritePosts: RealmSet<Post> = realmSetOf()
// Dictionary of child RealmObject type (value MUST be nullable)
var postByYear: RealmDictionary<Post?> = realmDictionaryOf()
}

Luego, defina una propiedad de vínculos de retroceso inmutables en el objeto secundario RealmResults<E> de, donde <E> es el tipo de objeto principal:

// Backlink of RealmObject must be RealmResults<E> of parent object type
class Post : RealmObject {
var title: String = ""
var date: RealmInstant = RealmInstant.now()
// Backlink to parent RealmObject type (CANNOT be null & MUST be val)
val user: RealmResults<User> by backlinks(User::posts)
}

Un objeto incrustado es un tipo especial de objeto Realm que permite anidar datos dentro de un único objeto principal específico. Los objetos incrustados pueden tener una relación uno a uno, uno a muchos o inversa, similar a las relaciones descritas en las secciones anteriores, excepto que la relación se limita a una relación uno a uno entre un único objeto principal y un EmbeddedRealmObject tipo.

Dado que los objetos incrustados no pueden existir como objetos Realm independientes, tienen restricciones adicionales a considerar:

  • Un objeto incrustado tiene propiedad estricta de su padre. No se pueden compartir objetos incrustados entre objetos padres.

  • El objeto incrustado hereda el ciclo de vida de su elemento principal. Por ejemplo, al eliminar el elemento principal, también se elimina el objeto incrustado.

Los objetos incrustados son útiles cuando existe una clara relación de contención o propiedad. Por ejemplo, un objeto Address podría estar incrustado en un objeto User porque solo tiene sentido en la aplicación dentro del contexto de un usuario.

Tip

Los tipos de objetos incrustados son reutilizables y componibles

Puede utilizar el mismo tipo de objeto incrustado en varios tipos de objetos principales y dentro de otros tipos de objetos incrustados.

Para definir un objeto incrustado con una relación uno a uno con su padre, defina una propiedad de objeto cuyo tipo sea un EmbeddedRealmObject ya definido en su modelo de datos:

// To-one embedded relationships must be of EmbeddedRealmObject type
class Contact : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var name: String = ""
// Property of EmbeddedRealmObject type (MUST be null)
var address: EmbeddedAddress? = null
}
class EmbeddedAddress : EmbeddedRealmObject {
var propertyOwner: Contact? = null
var street: String? = ""
// Embed another EmbeddedRealmObject type
var country: EmbeddedCountry? = null
}
class EmbeddedCountry : EmbeddedRealmObject {
var name: String = ""
}

Para definir un objeto incrustado con una relación uno a muchos incrustada con su elemento primario, se debe definir una propiedad de objeto cuyo tipo sea un RealmList<E>, donde <E> es un tipo de objeto Realm EmbeddedRealmObject definido en su modelo de datos:

// To-many embedded relationships must be a RealmList<E> or
// RealmDictionary<K, V> property of EmbeddedRealmObject type
class Business : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var name: String = ""
// List of EmbeddedRealmObject type (CANNOT be null)
var addresses: RealmList<EmbeddedAddress> = realmListOf()
// Dictionary of EmbeddedRealmObject type (value MUST be nullable)
var addressByYear: RealmDictionary<EmbeddedAddress?> = realmDictionaryOf()
}

No se puede definir un objeto incrustado con un RealmSet<E> tipo, ya RealmSet<E> que no admite objetos incrustados.

Para definir un objeto incrustado con una relación inversa con su padre, primero defina una propiedad de colección en el objeto padre cuyo tipo sea RealmList<E> o RealmDictionary<E>, donde <E> es un tipo de objeto EmbeddedRealmObject definido en su modelo de datos:

// Parent object must have RealmList<E> or RealmDictionary<K, V>
// property of child EmbeddedRealmObject type
class User : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var name: String = ""
// List of child EmbeddedRealmObject type (CANNOT be nullable)
var posts: RealmList<Post> = realmListOf()
// Dictionary of child EmbeddedRealmObject type (value MUST be nullable)
var postByYear: RealmDictionary<Post?> = realmDictionaryOf()
}

No se puede definir un objeto incrustado con un RealmSet<E> tipo, ya RealmSet<E> que no admite objetos incrustados.

Luego, defina una propiedad de vínculos de retroceso inmutables en el objeto secundario cuyo tipo sea el tipo del objeto principal:

// Backlink of EmbeddedRealmObject must be parent object type
class Post : EmbeddedRealmObject {
var title: String = ""
var date: RealmInstant = RealmInstant.now()
// Backlink to parent RealmObject type (CANNOT be null & MUST be val)
val user: User by backlinks(User::posts)
}

Volver

Anotaciones de propiedad

En esta página