领域模型中的单一反向关系
Single inverse relationship in Realm models
我正在开发一个简单的 iOS 应用程序来学习 Swift 并且我正在使用 Realm。
据我所知,在 Realm 中,反向关系是通过 LinkingObjects
属性 实现的,它是一个包含所有链接到该对象的对象的集合。
考虑领域文档中的这个例子:
class Person: Object {
// ... other property declarations
let dogs = List<Dog>()
}
class Dog: Object {
dynamic var name = ""
dynamic var age = 0
let owners = LinkingObjects(fromType: Person.self, property: "dogs")
}
在我的模型中,我知道每个 Dog
实例将只有 一个 所有者,因为每只狗在创建时仅添加到一个 Person
的 List
.
现在我想在 Dog
class 中有一个 owner: Person
属性 引用它的唯一所有者以使代码更直观和更简单(而不是每次都写 dog.owners.first
),同时保持 延迟加载 行为(它们是延迟加载的,对吧?)。
我不知道查询 "Linking Objects" 的开销有多大,但由于周围会有很多 "Dogs",我认为最好不要在对象初始化时访问它们。
目前我能想到的解决办法是:
1:
class Dog: Object {
let owner: Person = LinkingObjects(fromType: Person.self, property: "dogs").first!
}
2a:
class Dog: Object {
private let owners = LinkingObjects(fromType: Person.self, property: "dogs")
lazy var owner: Person = {return self.owners.first!}()
}
2b:
class Dog: Object {
lazy var owner: Person = {
return LinkingObjects(fromType: Person.self, property: "dogs").first!
}()
}
3:
class Dog: Object {
private let owners = LinkingObjects(fromType: Person.self, property: "dogs")
var owner: Person {
return self.owners.first!
}
}
我不认为 "solution 1" 是延迟加载的,与 "solution 2" 一样,owner
不会是 "auto-updating",但这不应该是一个问题,因为在我的情况下 Dog
永远不会改变所有者。
在 Swift 中有一个 单一 反向关系,你会推荐什么?
唯一的办法就是3。 1 和 2a, 2b 都不行。
因为目前LinkingObjects
只能用来初始化一个属性类型的LinkingObjects。 Realm 在初始化以定义数据模式时读取 class 定义和所有属性。在 1 的代码中,owner
属性 被视为只是 Person
属性.
2a 和 2b 也不起作用。因为 Realm 不支持 lazy
属性。另外 2b 以错误的方式使用 LinkingObjects
与 1.
所以,只有 3 按预期工作。
另见... https://github.com/realm/realm-cocoa/issues/3525#issuecomment-216920757
也许你可以在'one'端设置实际关系?
- 指定'one'端的连接
- 在 'many' 端的 getter 中进行查询:
所以它应该是这样的:
class Dog: Object {
dynamic var name:String = ""
dynamic var owner:Owner? = nil
}
class Ownder: Object {
dynamic var name:String = ""
var dogs:Results<Dog>? {
return realm?.objects(Dog).filter(NSPredicate(format: "owner == %@", self))
}
}
我正在开发一个简单的 iOS 应用程序来学习 Swift 并且我正在使用 Realm。
据我所知,在 Realm 中,反向关系是通过 LinkingObjects
属性 实现的,它是一个包含所有链接到该对象的对象的集合。
考虑领域文档中的这个例子:
class Person: Object {
// ... other property declarations
let dogs = List<Dog>()
}
class Dog: Object {
dynamic var name = ""
dynamic var age = 0
let owners = LinkingObjects(fromType: Person.self, property: "dogs")
}
在我的模型中,我知道每个 Dog
实例将只有 一个 所有者,因为每只狗在创建时仅添加到一个 Person
的 List
.
现在我想在 Dog
class 中有一个 owner: Person
属性 引用它的唯一所有者以使代码更直观和更简单(而不是每次都写 dog.owners.first
),同时保持 延迟加载 行为(它们是延迟加载的,对吧?)。
我不知道查询 "Linking Objects" 的开销有多大,但由于周围会有很多 "Dogs",我认为最好不要在对象初始化时访问它们。
目前我能想到的解决办法是:
1:
class Dog: Object {
let owner: Person = LinkingObjects(fromType: Person.self, property: "dogs").first!
}
2a:
class Dog: Object {
private let owners = LinkingObjects(fromType: Person.self, property: "dogs")
lazy var owner: Person = {return self.owners.first!}()
}
2b:
class Dog: Object {
lazy var owner: Person = {
return LinkingObjects(fromType: Person.self, property: "dogs").first!
}()
}
3:
class Dog: Object {
private let owners = LinkingObjects(fromType: Person.self, property: "dogs")
var owner: Person {
return self.owners.first!
}
}
我不认为 "solution 1" 是延迟加载的,与 "solution 2" 一样,owner
不会是 "auto-updating",但这不应该是一个问题,因为在我的情况下 Dog
永远不会改变所有者。
在 Swift 中有一个 单一 反向关系,你会推荐什么?
唯一的办法就是3。 1 和 2a, 2b 都不行。
因为目前LinkingObjects
只能用来初始化一个属性类型的LinkingObjects。 Realm 在初始化以定义数据模式时读取 class 定义和所有属性。在 1 的代码中,owner
属性 被视为只是 Person
属性.
2a 和 2b 也不起作用。因为 Realm 不支持 lazy
属性。另外 2b 以错误的方式使用 LinkingObjects
与 1.
所以,只有 3 按预期工作。
另见... https://github.com/realm/realm-cocoa/issues/3525#issuecomment-216920757
也许你可以在'one'端设置实际关系?
- 指定'one'端的连接
- 在 'many' 端的 getter 中进行查询:
所以它应该是这样的:
class Dog: Object {
dynamic var name:String = ""
dynamic var owner:Owner? = nil
}
class Ownder: Object {
dynamic var name:String = ""
var dogs:Results<Dog>? {
return realm?.objects(Dog).filter(NSPredicate(format: "owner == %@", self))
}
}