1

在我的 iOS 项目中,我使用GRDB来管理 SQLite 数据库。我尝试查询具有 1-1 关联的表。

在我的数据库中,假设我有 2 个表:

Selections
----------
- selectionId (primary key)
- position
- idSong (foreign key)

Songs
-----
- songId (primary key)
- name
- artist

这两个实体通过 1-1 关联链接,这要归功于idSong.

这是我尝试过的:

  • Selection实体:
class Selection : Record
{
    var selectionId: Int64?
    var position: Int?
    var idSong: Int64?

    static let song = hasOne(Song.self, key: "selectionId", using: ForeignKey(["songId"]))
    var song: QueryInterfaceRequest<Song> {
        request(for: Selection.song)
    }

    // ...
}
  • Song实体:
class Song : Record
{
    var songId: Int64?
    var name: String?
    var artist: String?

    static let selection = belongsTo(Selection.self)
    var selection: QueryInterfaceRequest<Selection> {
        request(for: Song.selection)
    }

    // ...
}
  • 一个SelectionSong结构:
struct SelectionSong : FetchableRecord
{
    let selection: Selection
    let song: Song
    
    
    init(row: Row)
    {
        selection = row[Selection.databaseTableName]
        song = row[Song.databaseTableName]
    }
}
  • 这是我创建这两个表的方式:
    // Selections:
    try db.create(table: Selection.databaseTableName) { table in
        
        table.autoIncrementedPrimaryKey("selectionId")
        table.column("position", .integer).notNull()
        table.column("idSong", .integer)
            .notNull()
            .indexed()
            .references(Song.databaseTableName, onDelete: .cascade)
    }

    // Songs:
    try db.create(table: Song.databaseTableName) { table in
        
        table.autoIncrementedPrimaryKey("songId")
        table.column("name", .text).notNull()
        table.column("artist", .text).notNull()
    }

  • 以下是我尝试获取 的列表的方法SelectionSong,因此我可以获得 的列表Selection,以及每个Selection相关的列表Song
    let request = Selection.including(optional: Selection.song)
    let list = try SelectionSong.fetchAll(db, request)

但后来我收到以下错误:missing scope 'song'

那么如何查询我的Selection表,以便获得SelectionSong(aSelection和关联的Song)列表?

谢谢。

4

1 回答 1

1

以下是要修复的几个错误:

  • Selection课堂上:
class Selection : Record
{
    var selectionId: Int64?
    var position: Int?
    var idSong: Int64?

    static let song = hasOne(Song.self, using: ForeignKey(["songId"], to: ["idSong"]))
    var song: QueryInterfaceRequest<Song> {
        request(for: Selection.song)
    }

    // ...
}
  • Song类中,去掉无用的代码,所以我们得到:
class Song : Record
{
    var songId: Int64?
    var name: String?
    var artist: String?

    // ...
}
  • 最后,在SelectionSong
struct SelectionSong : FetchableRecord
{
    let selection: Selection
    let song: Song
    
    
    init(row: Row)
    {
        selection = Selection(row: row)
        song = row["song"]
    }
}

如果您想使用自定义键而不是"song"in SelectionSong,请更改以下 in Selection

    static let song = hasOne(
        Song.self,
        key: "myCustomKey",
        using: ForeignKey(["songId"], to: ["idSong"]))
于 2021-01-29T20:25:10.067 回答