【问题标题】:Nested preloading in EctoEcto 中的嵌套预加载
【发布时间】:2016-11-11 02:41:47
【问题描述】:

我正在尝试在 ecto 中编写一个嵌套查询,该查询从 post 表中预加载 comments,然后在单独的查询中我为每个评论预加载 user。这看起来像:

post = Repo.preload(Repo.get(Post, id), [:comments])
comments = Repo.preload(post.comments, [:user])

问题在于,当我知道有一种方法可以在一个查询中加载我需要的所有数据时,它会在数据库上运行 3 个不同的查询。

join: assoc()有关系吗?

【问题讨论】:

  • 您是否希望这个确切的代码 只运行一个查询?或者您是否正在寻找另一种只需要一个查询的方法?在前一种情况下,这似乎是不可能的 - 您正在对执行查询的函数进行三个单独的调用。
  • 我正在寻找另一种方法来做与该代码相同的事情,但在一个查询中。所以它最终会像post = Repo.one(new_query)

标签: elixir phoenix-framework ecto


【解决方案1】:

(我在这里放了一个较晚的答案,仅供参考。)你可以试试这个:

Repo.preload(Repo.get(Post, id), [{:comments, :user}]).comments

或等效地,以下任一:

Repo.preload(Repo.get(Post, id), [comments: :user]).comments
Repo.preload(Repo.get(Post, id), comments: :user).comments

This blog post by tkowal 对构建嵌套预加载的语法有很好的解释。 This discussion between José Valim and a netizen 也很有用。

【讨论】:

    【解决方案2】:

    我认为没有办法通过一个查询来做到这一点,据我所知,您必须将 cmets 和用户加入到帖子中,如果有,比如说 50 个 cmets,您会有 50 行包含相同的用户,我不知道这是否适合您。我认为你可以通过 2 个查询来做到这一点,它会是这样的:

    comments_query = 
      Comment
      |> join(:inner, [c], u in assoc(c, :user))
      |> preload([c, u], user: u)
    post = Repo.preload(Repo.get(Post, id), comments: comments_query)
    

    我没有测试过代码,但我相信它应该可以工作,或者至少你明白了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-02
      • 2017-11-19
      • 1970-01-01
      相关资源
      最近更新 更多