You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Realm关联关系与嵌入对象:如何仅存储RealmObject引用?

解决Realm中仅存储对象引用且无需自动更新的问题

针对你的需求,这里有两种实用方案,无需依赖自动同步的RealmList:

方案一:存储关联对象的ObjectId列表

Realm虽然不强制外键约束,但你完全可以直接存储ObjectId的普通列表,替代托管的RealmList<RealmObject>。这种方式既实现了“存储引用”的目的,又不会触发自动更新——因为存的只是ID,而非Realm的托管关联。

修改后的代码示例:

class Actor : RealmObject {
    var _id: ObjectId = ObjectId()
    var name: String = ""
    var age: Int? = null
    // 存储关联电影的ObjectId列表,而非直接存Movie对象
    var movieIds: List<ObjectId> = listOf()
}

class Movie : RealmObject {
    var _id: ObjectId = ObjectId()
    var name: String = ""
    // 存储关联演员的ObjectId列表
    var actorIds: List<ObjectId> = listOf()
    var roles: List<String> = listOf() 
}

需要获取关联对象时,手动通过ObjectId查询即可:

// 示例:根据Actor的movieIds查询对应的电影
val actor = realm.find(Actor::class.java, actorId)
val movies = actor?.movieIds?.mapNotNull { movieId ->
    realm.find(Movie::class.java, movieId)
}

这种方式最接近你熟悉的SQL外键思路,完全符合“少用RealmObject类”的需求,不需要额外的交叉表。

方案二:存储非托管的对象副本

如果你需要直接存储对象的快照(而非ID),可以把关联对象转换成非托管副本,再存入普通List中。Realm的copyFromRealm()方法能把托管对象转换成脱离Realm管理的副本,后续原对象变更不会影响这个副本。

注意:Realm不允许直接在RealmObject中存储List<RealmObject>(非RealmList),所以需要先把Actor/Movie转换成普通数据类,再存储数据类的列表:

  1. 定义对应的数据类:
data class ActorDto(
    val _id: ObjectId,
    val name: String,
    val age: Int?
)

data class MovieDto(
    val _id: ObjectId,
    val name: String,
    val roles: List<String>
)
  1. 修改RealmObject类:
class Actor : RealmObject {
    var _id: ObjectId = ObjectId()
    var name: String = ""
    var age: Int? = null
    // 存储电影的非托管副本列表
    var movies: List<MovieDto> = listOf()
}

class Movie : RealmObject {
    var _id: ObjectId = ObjectId()
    var name: String = ""
    // 存储演员的非托管副本列表
    var actors: List<ActorDto> = listOf()
    var roles: List<String> = listOf() 
}
  1. 存入副本时的操作:
// 示例:将托管的Movie对象转换成Dto存入Actor
val managedMovie = realm.find(Movie::class.java, movieId)
val movieDto = managedMovie?.let {
    MovieDto(it._id, it.name, it.roles)
}
realm.executeTransaction {
    val actor = it.find(Actor::class.java, actorId)
    actor?.movies = actor?.movies.orEmpty() + listOfNotNull(movieDto)
}

这种方式存的是对象的快照,完全不受原对象变更影响,但需要额外定义数据类,适合需要直接使用对象属性而不想手动查询的场景。


内容的提问来源于stack exchange,提问作者Daniel M.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 11:47:54