【问题标题】:A nested include does not deliver result嵌套包含不提供结果
【发布时间】:2019-05-10 16:57:39
【问题描述】:

我有三个关联模型,Product、CatalogMembership、Catalog 与这些关联

Product.hasMany(CatalogMembership, { foreignKey: 'product_id' });
CatalogMembership.hasOne(Catalog, { targetKey: 'catalog_id', foreignKey: 'id' });

当我执行这个嵌套查询时

let products = await Product.findAll({
      where: {...},
      include: {
        model: CatalogMembership,
        where: { catalog_id: { [Op.in]: catalogIds } },
        include: {
          model: Catalog,
          attributes: ['name', 'id'],
        },
      },
    });

包含 CatalogMemberships,但目录为空:

console.log(products[0]) // -->
/*
{
  id: 1,
  catalog_memberships: [
    { id: 23,
      catalog_id: 15,
      catalog: null,
      ...
    },
    {
      id: 24,
      catalog_id: 16,
      catalog: null,
      ...
    }
  ],
  ...
}
*/

而且我确信有目录 CatalogMembership.catalog_id === Catalog.id

我预计目录属性不会为 null,而是类似

{
  id: 15,
  name: 'MyCatalog'
}

【问题讨论】:

    标签: sequelize.js


    【解决方案1】:

    hasOne 关系中没有 targetKey。有 foreignKey(目标表中外键属性的名称)和 sourceKey to(用作源表中关联键的属性名称) ,默认是源表的主键。

    所以这样使用,

    CatalogMembership.hasOne(Catalog, { foreignKey: 'catalog_id', sourceKey: 'id' });
    

    【讨论】:

      【解决方案2】:

      感谢您的回答。不幸的是,我的一般方法是错误的。我必须通过 CatalogMembership 与 Product 和 Catalog 建立 n:m 关联。所以我给 Product 和 Catalog 添加了一个 belongsToMany 关联。

      代码如下:

      const Product = sequelize.define('product', {
        <some column names>
        ...
      }, {
        timestamps: true,
        ...
      });
      
      const Catalog = sequelize.define('catalog', {
        <some column names>
        ...
      }, {
        timestamps: true,
        ...
      });
      
      
      const CatalogMembership = sequelize.define('catalog_membership', {
        product_id: { type: Sequelize.INTEGER },
        catalog_id: { type: Sequelize.INTEGER },
        ...
      }, {
        timestamps: true,
        ...
      });
      
      Product.belongsToMany(Catalog, { through: CatalogMembership, foreignKey: 'product_id', otherKey: 'catalog_id' });
      Catalog.belongsToMany(Product, { through: CatalogMembership, foreignKey: 'catalog_id', otherKey: 'product_id' });
      
      if (Meteor.isTest) {
        Product.sync();
        Catalog.sync();
        CatalogMembership.sync();
      }
      

      有了这些关联,就不需要嵌套查询了:

      let products = await Product.findAll({
            where: { ... },
            include: {
              model: Catalog,
              where: { id: { [Op.in]: catalogPostgresIds } },
              attributes: ['name', 'id'],
            },
            order: { ... },
          });
      

      【讨论】:

        猜你喜欢
        • 2022-01-26
        • 2017-05-28
        • 2014-02-03
        • 1970-01-01
        • 1970-01-01
        • 2017-10-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多