无法创建用于查询嵌套父项的 Fluent ORM 查询

问题描述

我有 3 个表,LastName、MiddleName 和 FirstName... FirstName 有 MiddleNameID 作为父级,MiddleName 有 LastName.id 作为父级

模型看起来像这样

final class LastName: Model,Content {
    static let schema = "lastnames"
    
    @ID(key: .id)
    var id: UUID?

    @Field(key: "name")
    var name: String

    
    @Children(for: \.$lastname)
    var middle_names: [MiddleName]
    
    init() { }

    init(id: UUID? = nil,name: String) {
        self.id = id
        self.name = name
    }
}

final class MiddleName: Model,Content {
    static let schema = "middlenames"
    
    @ID(key: .id)
    var id: UUID?

    @Parent(key: "last_name_id")
    var lastname: LastName
    
    @Field(key: "name")
    var name: String

    @Children(for: \.$middleNameId)
    var firstNames: [FirstName]
    
    init() { }

    init(id: UUID? = nil,lastname: LastName,name: String ) {
        self.id = id
        self.lastname = lastname
        self.name = name
    }
}


final class FirstName: Model,Content {
    static let schema = "firstnames"
    
    @ID(key: .id)
    var id: UUID?
    
    @Parent(key: "middle_name_id")
    var middleNameId: MiddleName
    
    
    @Field(key: "name")
    var name: String
   
    
    init() { }

    init(id: UUID? = nil,middleNameId: MiddleName,name: String) {
        self.id = id
        self.middleNameId = testBundleId
        self.name = name
    }
}

而且我想要查询,例如给我所有的名字记录,其中 lastname == Smith AND/OR middle == James ... 不知道如何使用 Fluent DSL 进行多重连接?或者给我所有与中间名和/或姓氏相匹配的名字

如果我必须写一个 sql 查询可能看起来像这样

                  SELECT disTINCT ON (ln.id,mn.id)
                  ln.name,mn.name,fn.*
                  FROM last_name ln
                  LEFT JOIN middle_name mn ON ln.id = mn.last_name_id
                  LEFT JOIN first_name fn ON fn.middle_name_id = mn.id
                  WHERE ( mn.name <> '' AND fn.name <> '' ) AND
                  (true AND ln.name ~ 'smith')
                  ORDER BY ln.id,mn.id,fn.id

解决方法

您可以在 Fluent 查询中执行此操作,例如:

return Lastname.query(on: req)
    .filter(\.$name == "Smith")
    .with(\.$middle_names) { $0.with(\.$firstnames) }
    .all()
    .flatMap { wholeNames in
    let result = wholeNames.filter { $0.middle_names.contains("James") }
    // continue
}

这将为您提供中间名是 James 的所有 Smiths。您可以将其用作 OR 变体的基础。它的工作原理是首先过滤 Smith 的姓氏,然后 with 连接中间名,但闭包确保也连接名字。

我认为没有办法将中间名过滤器构建到查询中,所以我认为您必须按照我所展示的那样进行。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...