LoginSignup
0
0

SeaORMで同一テーブルへの複数参照を一度に取得する

Last updated at Posted at 2024-05-26

前提のテーブル定義説明

同一テーブルへ複数参照を持つテーブルを扱う場合にleft joinで複数の参照を一度に取得する際にどうすればいいのか詰まってしまったので備忘も兼ねて記録、、
以下はアイテムテーブルと、その構成要素テーブルの関係です

item_bom - item(CraftedItem)
         - item(MaterialItem)

エンティティの定義は以下のような感じでした

// アイテム
mod item {
    pub struct Entity {
        pub id: i32
    }
}
// アイテム構成要素
mod item_bom {
    pub struct Entity {
        // 作成されるアイテムのID
        pub crafted_item_id: i32,
        // 素材アイテムのID
        pub material_item_id: i32,
        // 素材の必要数
        pub amount: i32
    }
}

取得コード

    // クエリの組み立て
    let query = item_bom::find()
        .join(
            JoinType::LeftJoin,
            item_bom::Relation::Item1
                .def()
                // on_conditionはデフォルトはAND条件になるが、ConditionType::Anyを指定すればOrになる
                .condition_type(sea_orm::sea_query::ConditionType::Any)
                .on_condition(|left, right| {
                    Expr::col((left, item_bom::Column::CraftedItemId))
                        .eq(Expr::col((right, item::Column::Id)))
                        .into_condition()
                }),
        )
        .select_also(item::Entity);
    
    // 生成するSQLのチェック
    println!("{:#?}", query.build(DbBackend::Postgres).to_string());
    
    // 結果取得
    let models = query.all(tx).await?;

ポイントとしてはjoinするときのcondition_typeをAnyにしてcraftedとmaterialのidを同時に指定することでした

改めて見返すとただのleftjoinにただ一文追加するだけか、、という気持ちですが、気づかずに数時間Relationこねくり回したりなんなりしてしまった、、
普段はC#を使っているのでこういうときにEFの偉大さを感じます😭

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0