【问题标题】:Filtering many-to-many relation by comparing objects agains keypath of objects in array with NSPredicate in swift通过将对象与数组中对象的键路径与 NSPredicate 进行快速比较来过滤多对多关系
【发布时间】:2015-11-05 10:04:45
【问题描述】:

我希望你能帮助我。我正在使用 Realm 作为底层数据库系统构建一个 Mac OS X 应用程序。

我的模型如下所示:

-Brick:由属性title和text组成的文本块

-GeneratorBrick:一个多对多关系对象,用于对Generator、Brick和其他一些与问题无关的数据之间的关系进行建模。此对象的属性称为“砖”

-Generator:由一些文本以及属性名称为“generatorBricks”的GeneratorBricks列表组成的配置

在我的应用程序中,我现在有一个 Generator 对象。这个包含一堆 GeneratorBrick 对象的列表,这些对象本身都有一个 Brick 和一些其他数据。我将它们显示在 TableView 中。我现在想显示另一个 TableView,其中我只显示那些不在当前生成器的 TableView 中的 Brick 对象。我访问的发电机中的砖块 generator.generatorBricks[index].brick

在我的应用程序的早期版本中,我通过var bricks: Results<Brick> = try! Realm().objects(Brick).sorted("title").filter("inGenerator = false") 加载了我需要的所有 Brick 对象,但由于我的模型从使用属性“inGenerator”更改为使用另一个模型类“GeneratorBrick”,我需要另一种过滤方式。不幸的是,我不知道如何完成这项任务。我尝试了不同的谓词,例如generatorBricks IN %@", generator.generatorBricks,其中属性“generatorBricks”是 Brick 类中的反向链接属性。

也许我正在尝试使用谓词无法完成的事情,或者我只是没有足够的谓词经验。也许我是盲人,因为我更习惯于纯 SQL,我会使用类似以下内容:

create table brick (
  id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  title varchar(255)
);
create table generator (
  id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  title varchar(255)
);

create table generatorbrick (
  id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  brickId INT(6),
  generatorId INT(6)
) 

select * from brick b join generatorbrick gb on b.id = gb.brickid where gb.generatorid is not 123

你明白我的问题吗?您需要更多信息吗?如果你能给我一个正确方向的提示,我很高兴提供。提前谢谢你。

【问题讨论】:

    标签: swift macos nspredicate realm


    【解决方案1】:

    您在传统 SQL 中使用(昂贵的)连接操作会做的事情,您应该在 Realm 中使用(便宜的)图关系做:

    class Brick: Object {
      dynamic var title = ""
    }
    class BrickGenerator: Object {
      dynamic var id = 0
      dynamic var title = ""
      dynamic var brick: Brick? = nil
    }
    
    let realm = try! Realm()
    let brick = realm.objects(BrickGenerator).filter("id != 123").first?.brick
    

    我不能 100% 确定这是否是您尝试建模的操作,而且我的印象是,如果我真正了解您想要完成的工作,这些模型可以进一步简化。

    但要点是 Realm 是一个图形数据库(不是关系型的),所以链接是本地表示的。试着想想如果你的模型是 100% 内存中的普通旧 Swift 对象(类/结构)会是什么样子。

    【讨论】:

    • 也许你可以看看项目的代码,你可以在这里找到github.com/xxtesaxx/Tube-Bricks
    • 看看 GeneratorViewController 类,我有这两个 TableView,其中一个显示所有可用的 Bricks,另一个显示来自当前 Generator 的 Bricks。每个 Brick 都可以有一个 Separator,这就是我创建 GeneratorBrick 类的原因,将 Generator、Brick 和 Separator 链接在一起。当然,一个 Brick 可以存在于多个生成器中,并且每个生成器中可以有不同的分隔符。你真的认为有办法简化这种关系吗?谢谢
    • 目标是只在左侧的 TableView 中显示右侧未显示的砖块。
    【解决方案2】:

    我得出的结论是,我想做的事情不是简单地通过基于图形的 Realm 就能实现的。至少在不加载所有砖块、generatorbricks 和生成器的情况下,并通过迭代所有砖块并检查它们是否是当前生成器的一部分来进行手动比较。

    我会需要类似的东西

    SELECT brick.* FROM brick JOIN generatorbrick on brick.id = generatorbrick.brickId JOIN generator on generator.id = generatorbrick.generatorId WHERE generator.id != 123

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-06
      • 2021-12-18
      • 2019-05-25
      • 1970-01-01
      相关资源
      最近更新 更多