【问题标题】:Realm - How to delete objects without any associated objects?领域 - 如何删除没有任何关联对象的对象?
【发布时间】:2019-07-09 03:53:23
【问题描述】:

在我的应用程序中,我从 Realm 加载存储的数据,然后调用 API 以获取用户对象的最新状态。之后我过滤哪些对象是新的,哪些应该被删除,就像这样:

// tracks is an array of objects downloaded from API and passed to the method
    let result = realm.objects(RealmTrack.self)

    print("Discovering new tracks")
    // Discover new tracks
    let new = tracks.filter({ track in
        !result.contains(where: { $0.trackUid == track.trackUid })
    })

    print("Discovering old tracks")
    // Discover old tracks in database
    let old = result.filter({ track in
        !tracks.contains(where: { $0.trackUid == track.trackUid })
    })

然后我正在向领域执行写入事务,它运行良好,没有任何错误。

    print("Modifying database")
        try realm.write {
            //realm.create(RealmTrack.self, value: realms, update: .modified)
            realm.add(realms, update: Realm.UpdatePolicy.modified)
            //realm.add(realms)
            realm.delete(old)
        }

我的问题是每个 RealmTrack 可以有其他关联的 Realm 对象:

dynamic var _primaryAlbum: RealmAlbum?

dynamic var _primaryArtist: RealmArtist?

RealmAlbumRealmArtist 都有一个 RealmTrack 对象列表:

let tracks = List<RealmTrack>()

删除旧曲目后,我怎样才能获得没有任何关联 RealmTrack 的剩余 RealmAlbumRealmArtist? 我也必须删除它们

我尝试的是在写事务块之后,检查哪些对象有空列表,但令人惊讶的是它总是0:

//realm.objects(RealmAlbum.self).count always returns 0 here
        let invalidatedAlbums = realm.objects(RealmAlbum.self).filter {
            $0.tracks.count == 0
            //$0.isInvalidated == true
        }

        let invalidatedArtists = realm.objects(RealmArtist.self).filter {
            $0.tracks.count == 0
            //$0.isInvalidated == true
        }

        try realm.write {
            realm.delete(invalidatedAlbums)
            realm.delete(invalidatedArtists)
        }

编辑:添加类声明

领域跟踪

@objcMembers class RealmTrack: Object, AWTrack {

        dynamic var _source: String = ""
        var source: AWMediaSource {
            return AWMediaSource(rawValue: _source)!
        }

        dynamic var _trackName: String = ""
        var trackName: String {
            return _trackName
        }

        dynamic var _trackUid: String = ""
        var trackUid: String {
            return _trackUid
        }

        dynamic var _playableUrl: String? = ""
        var playableUrl: String? {
            return _playableUrl
        }

        dynamic var _duration: TimeInterval = 0
        var duration: TimeInterval {
            return _duration
        }

        dynamic var _albumTrackNumber: Int = 0
        var albumTrackNumber: Int {
            return _albumTrackNumber
        }

        dynamic var _localizedTitle: String = ""
        var localizedTitle: String {
            return _localizedTitle
        }

        dynamic var _localizedAlbumTitle: String = ""
        var localizedAlbumTitle: String {
            return _localizedAlbumTitle
        }

        dynamic var _localizedAlbumArtist: String = ""
        var localizedAlbumArtist: String {
            return _localizedAlbumArtist
        }

        dynamic var _localizedArtist: String = ""
        var localizedArtist: String {
            return _localizedArtist
        }

        dynamic var _albumUid: String = ""
        var albumUid: String {
            return _albumUid
        }

        dynamic var _artistUid: String = ""
        var artistUid: String {
            return _artistUid
        }

        dynamic var _primaryAlbum: RealmAlbum?
        var primaryAlbum: AWAlbum? {
            return _primaryAlbum
        }

        dynamic var _primaryArtist: RealmArtist?
        var primaryArtist: AWArtist? {
            return _primaryArtist
        }

        override class func primaryKey() -> String? {
            return "_trackUid"
        }

RealmAbum

@objcMembers class RealmAlbum: Object, AWAlbum {

dynamic var _source: String = ""
var source: AWMediaSource {
    return AWMediaSource(rawValue: _source)!
}

dynamic var _albumName: String = ""
var albumName: String {
    return _albumName
}

dynamic var _albumUid: String = ""
var albumUid: String {
    return _albumUid
}

dynamic var _artistName: String = ""
var artistName: String {
    return _artistName
}

let tracks = List<RealmTrack>()

dynamic var _primaryArtist: RealmArtist?
var primaryArtist: AWArtist? {
    return _primaryArtist
}

override class func primaryKey() -> String? {
    return "_albumUid"
}

现实艺术家

@objcMembers class RealmArtist: Object, AWArtist {

dynamic var _source: String = ""
var source: AWMediaSource {
    return AWMediaSource(rawValue: _source)!
}

dynamic var _artistUid: String = ""
var artistUid: String {
    return _artistUid
}

dynamic var _artistName: String = ""
var artistName: String {
    return _artistName
}


let tracks = List<RealmTrack>()

override class func primaryKey() -> String? {
    return "_artistUid"
}

【问题讨论】:

  • 您是否尝试过将对象链接到来自 RealmAlbum 和 RealmArtist 的曲目?
  • 我确信这是通过在 RealmAlbum 或 RealmArtist 中创建对象列表自动完成的
  • 在这种情况下,您没有足够的 Realm 架构来给您一个决定性的答案。请添加 RealmAlbum、RealmArtist 和 RealmTrack 类。从技术上讲,只知道哪个链接到哪个(以及使用什么类型的链接)就足够了。
  • 我在问题中添加了类声明
  • 谢谢。这是一个棘手的情况。在这种情况下,您的 RealmAlbum/RealmArtist 有一个曲目列表;您可以使用 LinkingObjects 退出 primaryAlbum/primaryArtist。但是,您可以做的(因为您有 primaryAlbumprimaryArtist 字段)是通过专辑中的primaryAlbum 和艺术家中的primaryArtist 创建 LinkingObjects;您可以创建一个查询来检查这些链接对象的计数。如果 primary* 没有指向此艺术家/专辑的曲目,则没有与之关联的曲目。假设 1 首曲目始终属于 1 位艺术家/1 张专辑。

标签: ios swift realm


【解决方案1】:

这个问题的全部范围对我来说有点不清楚,所以我可能不完全理解被问到的内容,所以让我尝试回答这个问题:

如何查询列表属性中没有任何内容的对象。

如果您的对象具有其他对象的列表属性,如下所示:

class PersonClass: Object {
   @objc dynamic var person_name = ""
   let dogs = List<DogClass>()
}

class DogClass: Object {
   @objc dynamic var dog_name = ""
}

假设你有一个人的列表中有两只狗,然后一个人的列表中没有狗。您的目标是查询所有列表中没有狗的人。

let personResults = realm.objects(PersonClass.self).filter("dogs.@count == 0")

@count 是 List 和 Results 属性支持的聚合表达式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-28
    • 2022-01-07
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    相关资源
    最近更新 更多