0

假设我有一个非常简单的带有外键的数据库(为简单起见:一个带有自引用的表;上下文 - 对金融工具进行建模):

Instrument
    ticker String
    name String
    denomination InstrumentId -- FK !!
    domicile Country
    source DataSource
    UniqueT ticker
    deriving Eq Show

然后我可以通过执行获取所有行:

getAll :: (MonadIO m, MonadLogger m) => SqlReadT m [Entity Instrument]
getAll = select $ from $ return

我注意到我可以使用自动生成的函数从结果中提取特定字段,例如

getTicker :: Entity Instrument -> String
getTicker = instrumentTicker . entityVal

但是,当我尝试引用通过外键引用的值时,我得到:

getDenomination :: Entity Instrument -> Key Instrument
getDenomination = instrumentDenomination . entityVal

我的问题:如何引用与收到的“关键工具”相对应的剩余值,例如如何获取引用记录的“名称”字段?

编辑:

我试过写一个子查询,但到目前为止还不好。我尝试的是:

getInstrumentByKey :: (MonadIO m, MonadLogger m) => Key Instrument -> SqlBackendT m (Entity Instrument)
getInstrumentByKey key =
    select $ from $ \i ->
        where_ (i ^. InstrumentId ==. key)  -- type error, InstrumentKey is of type "SqlExpr (Value (Key Instrument))", while key is "Key Instrument"
        return i

如何在我的子查询中正确使用“Key Instrument”参数?

4

1 回答 1

1

稍微扩展一下我在评论中所说的内容:

总的来说,您有两种选择。一种是按 ID 进行另一次查找,如Persistent 文档中所述(请参阅“按 ID 获取”部分)。这并不理想,因为它涉及到数据库的第二次访问。

但由于您显然使用的是 SQL 数据库,这正是连接的用途。而且您已经在使用 Esqueleto,它允许您将 SQL 查询(包括连接(仅用 Persistent 无法表达))“翻译”成 Haskell。在这种情况下,您将使用denomination字段和 ID 将表连接到自身。同样,图书馆的文档很容易理解。

于 2020-03-31T21:57:48.980 回答