如何从另一个对象中的引用查询Realm对象?

时间:2022-02-20 19:38:06
class Person: Object {
  @objc dynamic var id: String = UUID().uuidString
  @objc dynamic var name: String = ""

  override static func primaryKey() -> String? {
    return "id"
  }
}
class Address: Object {
  @objc dynamic var id: String = UUID().uuidString
  @objc dynamic var line1: String = ""
  @objc dynamic var line2: String = ""
  @objc dynamic var city: String = ""
  @objc dynamic var state: String = ""
  @objc dynamic var country: String = ""

  override static func primaryKey() -> String? {
    return "id"
  }
}
class AssignedPersonAddress: Object {
  @objc dynamic var id: String = UUID().uuidString
  @objc dynamic var person: Person!
  @objc dynamic var address: Address!
  @objc dynamic var type: String = "" // 'Home', 'Work', etc...

  override static func primaryKey() -> String? {
    return "id"
  }
}

In order to record the type of address e.g. 'Home', 'Work', etc. the third table AssignedPersonAddress is required.

为了记录地址的类型,例如'Home','Work'等第三个表AssignedPersonAddress是必需的。

Person -* AssignedPersonAddress *- Address

How can I get an array (List) of the people associated with a particular address ?

如何获取与特定地址关联的人员的数组(列表)?

let address = SomeAddress

This next line never returns any records even though database has records for the address - correction - I have to subscribe to the query and wait for notifications before any records become visible.

即使数据库有地址记录,下一行也永远不会返回任何记录 - 更正 - 我必须订阅查询并在任何记录可见之前等待通知。

let assignedPersonAddresses = realm.objects(AssignedPersonAddress.self).filter("address == %@", address!)

Actually the line above throws an error about serialising a reference to an object but the following works

实际上,上面的行引发了关于序列化对象引用的错误,但以下工作

let assignedPersonAddresses = realm.objects(AssignedPersonAddress.self).filter("address.id == %@", address.id!)

It is also necessary to subscribe to notifications and only attempt to reference the results once the change notifications have been received. And then I figured I could flatMap{$0.person} the results to get just the list of Persons - but that doesn't really work unless the tableView data is reloaded completely each time.

订阅通知也是必要的,并且只有在收到更改通知后才尝试引用结果。然后我想我可以flatMap {$ 0.person}结果只获得人员列表 - 但除非每次都重新加载tableView数据,否则这不会真正起作用。

let peopleAtAddress = ??

Typical SQL would be something like:

典型的SQL类似于:

"select * from Person where id in (select distinct(personId) from AssignedPersonAddress where address = selectedAddress)"

EDIT:

For now I have added a List of people to the Address object in the model which gets updated any time there is a change to the AssignedPersonAddress records.

现在我已经在模型中的Address对象中添加了一个人员列表,只要对AssignedPersonAddress记录进行了更改,它就会更新。

1 个解决方案

#1


0  

If do you need Person type of Results<Person> you can try this code

如果您需要人员类型的结果 <人员> ,您可以尝试此代码

  let realm = try! Realm()

    var notificationToken: NotificationToken?


  try!  realm.write {

    let addressList  = realm.objects(AssignedPersonAddress.self)
    let personsId:[String] = addressList.filter({$0.id == "1"}).map({$0.person.id})
    let persons = realm.objects(Person.self).filter(NSPredicate(format: "(id IN %@)",personsId))

   notificationToken =  addressList.realm?.observe({ (note, realm) in
    ......
    let personsId:[String] = addressList.filter({$0.id == "1"}).map({$0.person.id})

    let persons = realm.objects(Person.self).filter(NSPredicate(format: "(id IN %@)",personsId))

    .....
    })


    }

#1


0  

If do you need Person type of Results<Person> you can try this code

如果您需要人员类型的结果 <人员> ,您可以尝试此代码

  let realm = try! Realm()

    var notificationToken: NotificationToken?


  try!  realm.write {

    let addressList  = realm.objects(AssignedPersonAddress.self)
    let personsId:[String] = addressList.filter({$0.id == "1"}).map({$0.person.id})
    let persons = realm.objects(Person.self).filter(NSPredicate(format: "(id IN %@)",personsId))

   notificationToken =  addressList.realm?.observe({ (note, realm) in
    ......
    let personsId:[String] = addressList.filter({$0.id == "1"}).map({$0.person.id})

    let persons = realm.objects(Person.self).filter(NSPredicate(format: "(id IN %@)",personsId))

    .....
    })


    }